访问路径:http://localhost:8081/oauth/token?grant_type=client_credentials&client_id=app&client_secret=app
如果我们在请求中添加了scope参数则会对该参数进行校验,没设置并不会报错

112行,验证请求中是否设置了grant_type参数,若没有设置则抛出异常
随后判断是否为隐式授权、是否授权码授权、是否时刷新令牌的请求
生成Token的逻辑
OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest)
getTokenGranter()获得一个TokenGranter的匿名对象


该匿名对象中含有一个CompositeTokenGranter对象,由上图可以,在创建CompositeTokenGranter对象时会注入一个TokenGranter集合,通过遍历TokenGranter集合找到能处理grantType类型的TokenGranter对象


第61行,会验证单位详情中是否包含我们所使用的grantType,由于我们使用的grantType为client_credentials,所以在oauth_client_details表的authorized_grant_types字段中须含有client_credentials
由于我们在配置类中并未设置tokenService,系统中默认使用DefaultTokenServices


默认支持RefreshToken和ReuseRefreshToken
调用DefaultTokenServices.createAccessToken()创建token
判断是否支持刷新Token
- 当
ClientDetailService对象不为空时则验证单位明细表中的authorized_grant_types字段是否包含refresh_token,若存在则支持 - 当
ClientDetailService对象为空时,则采用默认设置
刷新令牌的有效时间,若设置了则采用自定义的,若未设置则采用默认值
private int refreshTokenValiditySeconds = 60 * 60 * 24 * 30; // default 30 days.

refreshToken 值由 UUID 生成
访问令牌的有效时间,若设置了则采用自定义的,若未设置则采用默认值
private int accessTokenValiditySeconds = 60 * 60 * 12; // default 12 hours.
accessToken 值由 UUID 生成

tokenEnhancer 可以帮助我们在token中增加自定义信息
/**
* Created by liuquan on 2019/8/31.
*/
public class CustomTokenEnhancer implements TokenEnhancer{
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Map<String, Object> additionalInfo = new HashMap<String, Object>();
additionalInfo.put("resourceId","app");
((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
}
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancer());
}
@Bean
public TokenEnhancer tokenEnhancer(){
return new CustomTokenEnhancer();
}

为什么明明已经生成了RefreshToken,可返回信息中却没有?
我们回到ClientCredentialsTokenGranter一探究尽,原来是默认不允许刷新,最后将RefreshToken置为null

可以看到ClientCredentialsTokenGranter提供了setter方法对allowRefresh属性进行设置,我们将对之前的配置文件(【Spring Security OAuth2】客户端授权模式(client credentials)~授权服务配置)进行调整,以便我们可以获取到RefreshToken
public class CustomAuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore());
ClientDetailsService clientDetails = jdbcClientDetailsService();
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore());
tokenServices.setSupportRefreshToken(true);
tokenServices.setReuseRefreshToken(true);
tokenServices.setClientDetailsService(clientDetails);
tokenServices.setTokenEnhancer(tokenEnhancer());
OAuth2RequestFactory requestFactory = new DefaultOAuth2RequestFactory(clientDetails);
ClientCredentialsTokenGranter tokenGranter = new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory);
tokenGranter.setAllowRefresh(true);
endpoints.tokenGranter(tokenGranter);
}
@Bean
public TokenEnhancer tokenEnhancer(){
return new CustomTokenEnhancer();
}
}

此处的自定义配置是参考的框架中的默认配置
本文深入解析OAuth2中Token的生成流程,包括对grant_type参数的校验、不同授权类型处理、TokenGranter对象的工作原理及如何通过自定义配置支持刷新Token。

8896

被折叠的 条评论
为什么被折叠?



