当前位置: 代码迷 >> 综合 >> 【Spring Security OAuth2】客户端授权模式(client credentials)~获取访问令牌
  详细解决方案

【Spring Security OAuth2】客户端授权模式(client credentials)~获取访问令牌

热度:90   发布时间:2023-12-08 17:17:23.0

访问路径: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
在这里插入图片描述
在这里插入图片描述
默认支持RefreshTokenReuseRefreshToken

调用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();}}

在这里插入图片描述
此处的自定义配置是参考的框架中的默认配置

  相关解决方案