Spring Security OAuth2 token 源码处理逻辑
公司项目使用OAuth2做登录,主要使用Spring Security OAuth2搭建的授权服务器和资源服务器,文档可参考官方指导文档 https://projects.spring.io/spring-security-oauth/docs/oauth2.html,对于accessToken 和refreshToken看下代码中是如何生成和存储的,稍做记录。
调用/oauth/token获取token:
1.用的post方式调用,所以进入了org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken
通过clientId从数据库中读取了该clientId对应的记录authenticatedClient ,该变量的值包含:
ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId);
其中accessTokenValiditySeconds是acessToken的过期时间,对应于数据库字段access_token_validity,同样refreshTokenValiditySeconds是refreshToken过期时间,对应数据库字段refresh_token_validity。
生成token:
OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);
授权服务器配置时configure(AuthorizationServerEndpointsConfigurer endpoints)
方法内配置了endpoints.tokenGranter(new CompositeTokenGranter(tokenGranters));
,所以
getTokenGranter()获取到了CompositeTokenGranter实现。根据传入参数的grantType,进入grant方法内:
然后匹配grantType后进入对应grant方法执行,如AbstractTokenGranter.grant()方法,
该方法内再次根据clientId获取了ClientDetails信息并校验是否支持本次请求grantType类型,然后再进入getAccessToken()方法,然后再进入了DefaultTokenServices.createAccessToken()方法:
首次登录existingAccessToken为null,此时将会创建refreshTokenif (refreshToken == null) { refreshToken = createRefreshToken(authentication); }
,创建前先验证authorized_grant_types是否包含refresh_token,也就是又会根据clientId再查询一次ClientDetails。
调试进入createRefreshToken()方法发现方法内isSupportRefreshToken()和getRefreshTokenValiditySeconds()方法各根据clientId加载了一次数据。创建完refreshToken返回createAccessToken()方法,进入createAccessToken()方法,
不出意外再次加载了一次ClientDetails,获取accessToken的过期时间,同时设置了上一步生成的refreshToken以及设置scope,然后就是生成token内容了,如在授权服务器configure(AuthorizationServerEndpointsConfigurer endpoints)方法内设置了endpoints.accessTokenConverter()则此时将进入执行。执行完后返回createAccessToken()执行tokenStore.storeAccessToken(accessToken, authentication);
此方法也就是将生成的accessToken存储并设置过期时间,执行完后如果refreshToken不为空则存储refreshToken,然后再一步步返回