这是一个 3 篇系列文章,探讨为基于Spring Boot 2的应用程序使用 OAuth2 提供程序实现单点登录(SSO)的方法。文章将涵盖以下内容:
- 引导符合 OpenID Connect 的 OAuth2 授权服务器/OpenID 提供程序的方法。
- 与 OAuth2 授权服务器/OpenID 提供程序集成的传统 Spring Boot/Spring 5 方法。
- 与 OAuth2 授权服务器/OpenID 提供程序集成的较新 Spring Boot 2/Spring 5 方法。
本文将涵盖在本地计算机上引导运行符合 OpenID Connect 的 OAuth2 授权服务器的方法。
本质上,这是对之前一篇文章[http://www.java-allandsundry....]的重新整理,该文章详细介绍了使用出色的Cloud Foundry UAA 项目引导 OAuth2 授权服务器的过程。与之前的文章相比有一些变化,作者希望重新记录启动授权服务器的步骤,并更强调使其符合OpenID Connect的更改。
获取本地运行的健壮 OAuth2 授权服务器版本的最佳方法是使用出色的Cloud Foundry UAA项目。
步骤 1:克隆项目:
git clone https://github.com/cloudfoundry/uaa
步骤 2:生成密钥对
UAA 可以使用非对称 RSA 密钥对进行签名,并让客户端验证签名。作者提供了一个方便的脚本,用于生成密钥对并生成可用于引导 UAA 的配置文件:
#!/bin/bash
openssl genrsa -out privkey.pem 2048
openssl rsa -pubout -in privkey.pem -out pubkey.pem
SIGNING_KEY=$(cat privkey.pem)
VERIFICATION_KEY=$(cat pubkey.pem)
JWT_SIGNING_KEYS=$(cat <<EOF
jwt:
token:
signing-key: |
$(echo "$SIGNING_KEY" | awk '{printf " %s\n", $0}')
verification-key: |
$(echo "$VERIFICATION_KEY" | awk '{printf " %s\n", $0}')
EOF
)
echo "$JWT_SIGNING_KEYS" > uaa_config.yml
rm privkey.pem
rm pubkey.pem
运行此脚本后,将创建一个 UAA 配置,如下所示:
jwt:
token:
signing-key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuE5Ds...5Nka1vOTnjDgKIfsN
NTAI25qNNCZOXXnGp71gMWsXcLFq4JDJTovL4/rzPIip/1xU0LjFSw==
-----END RSA PRIVATE KEY-----
verification-key: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuE5DsCmjfvWArlCIOL6n
ZwIDAQAB
-----END PUBLIC KEY-----
步骤 3:使用配置启动 UAA 服务器:
UAA_CONFIG_URL=file://$PWD/uaa_config.yml./gradlew run
步骤 4:验证
验证 UAA 是否启动的一种快速方法是检查 JWKS_URI,这是一个公开客户端可用于验证令牌的验证密钥集的端点。对于 UAA,此端点可在"/token_keys"端点获得。可以使用 curl 或httpie验证此端点:
http GET http://localhost:8080/uaa/token_keys
# 或
curl http://localhost:8080/uaa/token_keys
如果配置正确,此端点应输出以下形式的内容:
{
"keys": [
{
"alg": "RS256",
"e": "AQAB",
"kid": "legacy-token-key",
"kty": "RSA",
"n": "APLeBV3dcUrWuVEXRyFzNaOTeKOLwFjscxbWFGofCkxrp3r0nRbBBb4ElG4qYzmbStg5o-zXAPCOu7Pqy2j4PtC3OxLHWnKsflNOEWTeXhLkPE0IptHPbc6zgVPP3EoiG_umpm0BYeJPZZc-7tA11uU_3NqidY9wnpOgKBuwNmdoyUrjb4fBDoMr_Wk2_sn_mtHSG8HaX8eJ9SbC9xRCJySjJDApOYR_dKjuwpbcM2ITfbTzD9M2J7yOtoJRkFhd1Ug2t_6AA_z47BBws-x9BBfSNbYGsVlDAbe6NK_jUE",
"use": "sig",
"value": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8t4FXd1xSta5URdHIXM1\no5N4o4vAWOxzFtYUah8KTGunevSdFsEFvgSUbipjOZtK2Dmj7NcA8I67s+rLaPg+\n0Lc7Esdacqx+U04RZN5eEuQ8TQim0c9tzrOBU8/cSiIb+6ambQF62glGQWF3VSDa3/oAD/PjsEHCz7H0EF9I1tgaxWUMBt7o0r+N\nQQIDAQAB\n-----END PUBLIC KEY-----"
}
]
}
步骤 5:填充数据
UAA 有一个名为uaac的配套 CLI 应用程序,可在此处获得[https://github.com/cloudfound...]。假设已下载 uaac CLI 并在默认端口 8080 启动了 UAA,首先将 uaac 指向 UAA 应用程序:
uaac target http://localhost:8080/uaa
然后使用其中一个预定义的客户端凭据(admin/adminsecret)登录:
uaac token client get admin -s adminsecret
现在客户端已登录,可以使用以下命令探索令牌:
uaac token decode
这将显示客户端中登录信息的详细信息:
jti: 4457847692b7464ca0320f08271a9e98
sub: admin
authorities: clients.read clients.secret clients.write uaa.admin clients.admin scim.write scim.read
scope: clients.read clients.secret clients.write uaa.admin clients.admin scim.write scim.read
client_id: admin
cid: admin
azp: admin
grant_type: client_credentials
rev_sig: 3c12911
iat: 1518332992
exp: 1518376192
iss: http://localhost:8080/uaa/oauth/token
zid: uaa
可以使用以下命令获取原始 JWT 令牌:
uaac context
它将输出如下内容:
[3]*[http://localhost:8080/uaa]
skip_ssl_validation: true
[2]*[admin]
client_id: admin
access_token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiI0NDU3ODQ3NjkyYjc0NjRjYTAzMjBmMDgyNzFhOWU5OCIsInN1YiI6ImFkbWluIiwiYXV0aG9yaXRpZXMiOlsiY2xpZW50cy5yZWFkIiwiY2xpZW50cy5zZWNyZXQiLCJjbGllbnRzLndyaXRlIiwidWFhLmFkbWluIiwiY2xpZW50cy5hZG1pbiIsInNjaW0ud3JpdGUiLCJzY2ltLnJlYWQiXSwic2NvcGUiOlsiY2xpZW50cy5yZWFkIiwiY2xpZW50cy5zZWNyZXQiLCJjbGllbnRzLndyaXRlIiwidWFhLmFkbWluIiwiY2xpZW50cy5hZG1pbiIsInNjaW0ud3JpdGUiLCJzY2ltLnJlYWQiXSwiY2xpZW50X2lkIjoiYWRtaW4iLCJjaWQiOiJhZG1pbiIsImF6cCI6ImFkbWluIiwiZ3JhbnRfdHlwZSI6ImNsaWVudF9jcmVkZW50aWFscyIsInJldl9zaWciOiIzYzEyOTExIiwiaWF0IjoxNTE4MzMyOTkyLCJleHAiOjE1MTgzNzYxOTIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC91YWEvb2F1dGgvdG9rZW4iLCJ6aWQiOiJ1YWEiLCJhdWQiOlsic2NpbSIsImNsaWVudHMiLCJ1YWEiLCJhZG1pbiJdfQ.ZEcUc4SvuwQYwdE0OeG5-l8Jh1HsP0JFI3aCob8A1zOcGOGjqso4j1-k_Lzm__pGZ702v4_CkoXOBXoqaaRbfVgJybBvOWbWsUZupMVMlEsyaR_j8DWY8utFAIiN2EsQgjG3qLrsf0K8lm0I3_UIEjaNZhSkWSLDLyY9wr_2SRanSf8LkcEJoSTTgDdO0aP8MvwNpDG7iQ2Om1HZEN08Bed1hHj6e1E277d9Kw7gutgCBht5GZDPFnI6Rjn0O5wimgrAa6FEDjdCpR7hy2P5RiOTcTvjj3rXtVJyVcQcxGKymZrY2WOx1mIEzEIAj8NYlw0TLuSVVOiNZ9fKlRiMpw
token_type: bearer
expires_in: 43199
scope: clients.read clients.secret clients.write uaa.admin clients.admin scim.write scim.read
jti: 4457847692b7464ca0320f08271a9e98
最后,要添加一个具有 client1/client1 凭据的客户端和一个具有 user1/user1 凭据的用户,请使用以下代码:
uaac client add client1 \
--name client1 \
--scope resource.read,resource.write,openid \
-s client1 \
--authorized_grant_types authorization_code,refresh_token,client_credentials,password \
--authorities uaa.resource \
--redirect_uri http://localhost:8888/**
# 添加一个名为 user1/user1 的用户
uaac user add user1 -p user1 --emails [email protected]
# 添加两个范围 resource.read, resource.write
uaac group add resource.read
uaac group add resource.write
# 为 user1 分配 resource.read 和 resource.write 两个范围..
uaac member add resource.read user1
uaac member add resource.write user1
此时,我们有一个工作的授权服务器,带有一个示例客户端和一个示例用户。后续文章将使用此数据为示例 Spring Boot2 应用程序启用身份验证。作者将在完成较新的文章后更新此文章中的链接。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。