访问样例
授权服务器源码剖析
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 !=null)BEGIN//如果有现存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