Oauth2源码剖析——密码式+数据库存储

访问样例

在这里插入图片描述

在这里插入图片描述

授权服务器源码剖析

TokenEndPoint.java
   ->postAccessToken(principal,parameters)
        -String clientId = getclientId(principal)//得到Authorization中的 clientId
        -ClientDetails authenticatedclient = getclientDetailsService().loadclientByClientId(clientId)//通过clientId拿到db中oauth_client_details 中的pwd等信息 
        -TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedclient)//将clientid,grantType,scope,params封装在一起 
        -OAuth2AccessToken token = getTokenGranter()grant(tokenRequest.getGrantType(),tokenRequest)//获取token
             ->AbstractTokenGranter.java
                 ->getAccessToken(client,tokenRequest)->tokenServices.createAccessToken(getOAuth2Authentication(client, tokenRequest));
                    -> getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest)//权限验证
                         ->ResourceOwnerPasswordTokenGranter.java-> userAuth = authenticationManager.authenticate(userAuth);
                             -ProviderManager.java-> result = provider.authenticate(authentication);//将参数里的username和pwd 与db中的User表字段进行recon,参数中的pwd会用BCryptPasswordEncoder进行相同方式的hash,再与db中的pwd进行比较是否一致
                                  ->AbstractUserDetailsAuthenticationProvider.java
                                       -public Authentication authenticate(Authentication authentication)//这里会进入两次,一次比较clinet_id和client_pwd,一次比较username和pwd
                                            ->user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);//得到ouath_details_client的数据或者通过UserDetailsService中自己实现的loadUSerByUsername()获得username和pwd
                                               -》additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);// check 数据是否正确
                   ->tokenServices.createAccessToken(getOAuth2Authentication(client, tokenRequest));
                      ->DefaultTokenService.java
                         ->createAccessToken(OAuth2Authentication authentication)//查看db,存储新的accesstoken
                            -OAuth2AccessToken existingAccessToken = tokenstore.getAccessToken(authentication);//查询db查看是否已经有Token
                             ->JdbcTokenStore.java
                                -> queryForObject(sql, return deserializeAccessToken(rs.getBytes(2));,key) //oauth_access_token查询是否已经有token  
                            -if (existingAccessToken !=nullBEGIN//如果有现存Token
                               -if (existingAccessToken.isExpired())BEGIN//如果已经过期了
                                  -if (existingAccessToken.getRefreshToken() != null->tokenStore.removeRefreshToken(refreshToken); //如果有refresh token 就删除refresh toke
                                  ->tokenStore.removeAccessToken(existingAccessToken);// remove access token
                               -> END
                            -> END
                            -OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken);//生成新的access token,并把refresh token,scope等信息存入 
                            -> tokenStore.storeAccessToken(accessToken,authentication);//access token 存入oauth_access_token
                                ->jdbcTemplate.update(insertAccessTokenSql,sq1 args,argTypes)//虽然jdbcTemplate调用的是update,其实是执行insertAccessTokenSq1,所以执行的是insert指令 
                            -> tokenStore.storeRefreshToken(refreshToken, authentication);//refresh token存入oauth_refresh_token
        ->getResponse(token);//返回response 

资源服务器源码剖析

CheckTokenEndpoint.java
  ->@RequestMapping(value = "/oauth/check_token")
	@ResponseBody
	public Map<String, ?> checkToken(@RequestParam("token") String value) //入口,参数是token
	  ->resourceServerTokenServices.readAccessToken(value); //读取token
	   -> DefaultTokenServices.java
	      -> JdbcTokenStore.java //根据不同的实现规则调用不同的Store方法
	        ->readAccessToken(String accessToken) 
	         ->jdbcTemplate.queryForObject(selectAccessTokenSql,..) //从db 拿到存储的token
	  -> loadAuthentication(String accessTokenValue) //读取权限
	     -> JdbcTokenStore.java //根据不同的实现规则调用不同的Store方法
	        ->readAccessToken(String accessToken) //再次读取db token
	        -> readAuthentication(String token) //从 oauth_clent_details里读取权限
	  -> accessTokenConverter.convertAccessToken(token, authentication); //①构建 response           
	  -> return response;   

① response
在这里插入图片描述

exp: 过期时间
user_name : 设置的用户名
authorities: 设置的role
client_id : 设置的
scope: 权限scope

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值