流程图
※:绿色的方块代表实体类;蓝色的方块代表接口(下方括号中的名称表示实际调用的实现类);
流程介绍
- step1:客户端发起获取令牌的请求:/oauth/token;
- step2:TokenEndpoint是整个流程的入口,可理解为一个controller,用来处理获取令牌的请求即:/oauth/token请求;
- step3:ClientDetailService用来读取请求中clientId中的详情;
- step4:ClientDetails将client的配置信息读入到一个clientDetail类中,里面封装了第三方应用的信息;
- step5:TokenRequest封装了请求中的参数信息,如:grant_type, username, password, socpe等 ,并将clientDetail的信息也放入tokenRequest中;
- step6:TokenGranter根据tokenRequest生成Oauth2Request和Authentication对象,Oauth2Request是clientDetail和TokenRequest的整合;Authentication封装了当前授权用户的信息;
- step7:Oauth2Authenticaiton由Oauth2Request和Authentication生成,里面封装了请求的用户信息、请求对象的信息、授权模式等;
- step8:AuthenticationServerTokenServices根据传入的Oauth2Authenticaiton最终生成token;
源码分析
TokenEndpoint:postAccessToken方法
@RequestMapping(value = "/oauth/token", method=RequestMethod.POST)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
if (!(principal instanceof Authentication)) {
throw new InsufficientAuthenticationException(
"There is no client authentication. Try adding an appropriate authentication filter.");
}
// 获取clientId, 参考下方getClientId方法
String clientId = getClientId(principal);
ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId);
// 生成tokenRequest,参考下方createTokenRequest方法
TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);
if (clientId != null && !clientId.equals("")) {
// Only validate the client details if a client authenticated during this
// request.
if (!clientId.equals(tokenRequest.getClientId())) {
// double ch