Spring Oauth2-Authorization-Server 授权码方式(Authorization_Code)
基于 spring-security-oauth2-authorization-server 0.2.3
授权码方式(Authorization_Code) 分两步:
- 根据client_id获取code
- 根据code 获取 access_token
配置 client 信息
@Bean
public RegisteredClientRepository jdbcRegisteredClientRepository(JdbcTemplate jdbcTemplate, PasswordEncoder passwordEncoder) {
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
// 客户端id 需要唯一
.clientId("apple")
// 客户端密码
.clientSecret(passwordEncoder.encode("apple_secret"))
// 默认基于 basic 的方式 认证 client_id和client_secret
// Base64.encode(string(client_id:clientSecret))
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
// 授权码
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
// 刷新token
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
// 客户端模式
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
// 密码模式, 目前没有实现
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
//废弃
.authorizationGrantType(AuthorizationGrantType.IMPLICIT)
// 重定向url
.redirectUri("https://www.baidu.com")
// 客户端申请的作用域,也可以理解这个客户端申请访问用户的哪些信息,比如:获取用户信息,获取用户照片等
.scope("user_info")
.scope("user_photo")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.tokenSettings(TokenSettings.builder()
//使用透明方式,默认是 OAuth2TokenFormat SELF_CONTAINED
.accessTokenFormat(OAuth2TokenFormat.REFERENCE)
// 授权码的有效期
.accessTokenTimeToLive(Duration.ofHours(1))
// 刷新token的有效期
.refreshTokenTimeToLive(Duration.ofDays(3))
.reuseRefreshTokens(true).build())
.build();
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
jdbcRegisteredClientRepository.save(registeredClient);
return jdbcRegisteredClientRepository;
}
根据client_id获取code
GET 请求,http://localhost:9000/oauth2/authorize?client_id=apple&response_type=code&redirect_uri=https://www.baidu.com&scope=user_info
,将这个url 放在浏览器上请求
没有登陆则需要登陆
同意授权:
重定向返回code:
根据 code 获取 access_token
在这个过程中,需要传client_id和client_secret, oauth2-authorization-server 提供了以下传递client_id 的方式, 即 clientAuthenticationMethod:
- client_secret_basic : 通过basic 方式提交,
Basic Base64.encode(string(client_id:clientSecret))
- 通过 OAuth2ClientAuthenticationFilter 拦截 basic
- client_secret_post: 将client_id, 和client_secret 放在 POST 表单中提交
- 同上
- client_secret_jwt: jwt 方式:
- 通过 BearerTokenAuthenticationFilter拦截 header 中
bearer {token}
- 通过 BearerTokenAuthenticationFilter拦截 header 中
- private_key_jwt
client_secret_basic
xiao@z:~$ curl -i -X POST \
-H "Authorization:Basic YXBwbGU6YXBwbGVfc2VjcmV0" \
'http://localhost:9000/oauth2/tokengrant_type=authorization_code\
&code=cfBlDunQUipgnyqihAaxYmptMwokapb4zKTXm1q_I4-Aa693shDLhcIn-qh5FSfyct8qOs\
&redirect_uri=https://www.baidu.com'
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 02 May 2022 07:24:43 GMT
{
"access_token": "Bmj_WYFDSrWyPPKrxHR6Qof8t1973",
"refresh_token": "HGRhp1WvFyJOHzdPQjYzyMuz10jBCCVD9EYL8y762qDp5Dqo",
"scope": "user_info",
"token_type": "Bearer",
"expires_in": 3599
}