持续更新Oauth2源码过程
1 . access_token生成过程/生成算法/如何判断是否过期
1.1 client第三方应用访问认证服务器获取授权码请求:localhost:7777/oauth/authorize?client_id=cms&response_type=code
1.2 跳转到认证服务器登陆页面,根据认证服务器预先颁发的账号,密匙登陆认证服务器,进入到授权页面
1.3点击授权,生成访问code=j73nPp
1.4 调用根据授权码获取access_token请求: http://localhost:7777/oauth/token?grant_type=authorization_code&code=j73nPp&client_id=cms&client_secret=secret 开始追踪源码
---> 进入到controller类 TokenEndpoint
OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);
---> tokenServices.createAccessToken(getOAuth2Authentication(client, tokenRequest));
--->InMemoryAuthorizationCodeServices取出对应保存的 授权码:访问信息
---->OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication); 通过访问信息判断是否已经存在此access_token existingAccessToken
----> 先创建refresh_token 再 OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken);创建对应的access_token
继续追踪 DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID().toString());生成access_token
也就是access_token其实生成算法是 UUID.randomUUID().toString()
--->对access_token进行丰富 例如设置过期时间,默认是12小时,授权范围
以及设置refresh_token
--->保存refresh_token
---> over 返回结果
2. 创建access_token过程中,为什么还有个refresh_token,有什么作用意义?
假设场景: 用户A在微博客户端,想访问QQ的相册,在OAuth2流程中表现形式,
1 微博端跳转到QQ端页面进行登陆授权
2 获取到QQ端的允许权限
3 微博得到一个access_token 进行api访问
缺陷场景 : 从安全的角度,会生成的access_token设置过期时间,例如我们设置这个access_token的过期时间为3分钟,那么相当于3分钟过后失效,3分钟后,用户A又得重复步骤 1,2,3 频繁打开QQ端 获取允许权限, 体验感极差,用户内心(what? see you rubbish)
refresh_token: 因此为了有效避免上述的缺陷,OAuth2 整出了这个双token机制
作用解释: 后续过程中,微博端 直接通过 refresh_token来获取,刷新过期/未过期的 access_token,不用再频繁打开QQ端获取允许权限
附. refresh_token 作用示例demo
上述我们回答了refresh_token的作用,这里也是搭建了一个demo工程做个功能演示
3.1 配置OAuth2
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {
//自定义拓展的鉴权类
@Autowired
private SecurityUserDetailsService securityUserDetailsService;
/**
* 用来配置授权(authorization)以及令牌(token)的访问端点和令牌服务(token services)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 使用内存保存生成的token
endpoints.authenticationManager(authenticationManager).tokenStore(memoryTokenStore());
endpoints.userDetailsService(securityUserDetailsService);
}
3.2 获取refresh_token http://localhost:7777/oauth/token?grant_type=authorization_code&code=gaZbvA&client_id=cms&client_secret=secret
3.3 通过refresh_token获取access_token http://localhost:7777/oauth/token?grant_type=refresh_token&client_id=cms&client_secret=secret&refresh_token=56149766-fc14-471d-afee-5b1492e64e28
3.4 校验步骤3.3 获取的access_token是否有效/校验成功
备注
后续补充refresh_token 作用源码过程