访问路径: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{
@Overridepublic OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Map<String, Object> additionalInfo = new HashMap<String, Object>();additionalInfo.put("resourceId","app");((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(additionalInfo);return accessToken;}
}
@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancer());}@Beanpublic TokenEnhancer tokenEnhancer(){
return new CustomTokenEnhancer();}
为什么明明已经生成了RefreshToken
,可返回信息中却没有?
我们回到ClientCredentialsTokenGranter
一探究尽,原来是默认不允许刷新,最后将RefreshToken
置为null
可以看到ClientCredentialsTokenGranter
提供了setter
方法对allowRefresh
属性进行设置,我们将对之前的配置文件(【Spring Security OAuth2】客户端授权模式(client credentials)~授权服务配置)进行调整,以便我们可以获取到RefreshToken
public class CustomAuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
@Overridepublic 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);}@Beanpublic TokenEnhancer tokenEnhancer(){
return new CustomTokenEnhancer();}}
此处的自定义配置是参考的框架中的默认配置