Spring Security OAuth2源码分析

1.Spring Security OAuth核心源码流程图:

在这里,先来简单描述一下每个类大概会做些什么,其工作职责是什么?

1.TokenEndpoint可以把它看成是一个controller,这是处理获取token请求的第一步:/oauth/token

2.当TokenEndpoint收到请求以后,会调用ClientDetailsService,这个有点像之前的UserDetailsService,但不同的是UserDetailsService读取的是用户信息,ClientDetailsService读取的是第三方应用信息

3.ClientDetails就是通过TokenEndpoint在调用ClientDetailsService中某个方法时所返回的对象,具体细节在后面源码分析的时候说

4.TokenRequest封装了我们的请求中其他的信息,比如grant_type等,同时也会直接把ClientDetails放到TokenRequest中

5.TokenGranter会根据前面TokenRequest中的grant_type传入的值来去挑一个具体的实现来执行对应的逻辑,但不管是哪一种实现,接下去都会产生两个东西 那就是OAuth2Request和Authentication

6.OAuth2Request实际上是前边ClientDetails和TokenRequest两个对象的信息整合出来的结果

7.Authentication封装了做授权的用户对应的信息

8.OAuth2Authentication是OAuth2Request和Authentication的组合体,这样到这里OAuth2Authentication就已经拥有了你授权信息,授权模式是什么等等信息,都最终会封装到OAuth2Authentication中

9.OAuth2Authentication最终会传给AuthorizationServerTokenServices这样一个接口的实现,他会将OAuth2Authentication转换为OAuth2AccessToken这样的一个令牌,最终返回给用户

(AuthorizationServerTokenServices)有两个实现类,TokenStore是用于定义令牌如何存储,TokenEnhancer是令牌增强器,当令牌生成后可以自定义增强令牌

2.Spring Security OAuth2 源码分析

还是这一张图,现在依照着这张图进行讲解:

我们先发送一个请求:

可以看到,现在请求进入了第一个类:

1.TokenEndpoint

请求进来以后,会先从请求里获取clientId

2.ClientDetailsService&ClientDetails:

ClientDetails authenticatedClient =getClientDetailsService().loadClientByClientId(clientId);

这行代码会获取第三方应用的信息,封装成ClientDetails对象

3.TokenRequest

TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);

这行代码开始创建tokenRequest,其中parameters是请求参数,authenticatedClient便是我们封装好的第三方应用信息

再进去看看这个方法做了什么

很明显,通过传进来的两个参数,获得了基本的请求参数和clientId,scopes,grantType等信息,也仅仅只是new了一个tokenRequest对象

继续往下走,是一堆判断逻辑

判断clientid是不是空的

判断scope,也就是这个client能够发出去什么授权?

判断granttype是否有值,一定要告诉security是四种授权模式的哪一种

判断是否简化模式如果是简化模式也将抛出异常

判断是否授权码模式的请求

判断是不是一个刷新令牌的请求

经过了一系列的判断,最终会传给TokenGranter

4.TokenGranter

前边经过了一系列的判断以后,请求终于传到了TokenGranter

之前我们说过,TokenGranter实际上是封装了四种授权模式加上刷新令牌这种模式来生成accessToken

进入它的实现类:CompositeTokenGranter中

看看这个遍历的集合tokenGranters是什么吧

很明显了,这就是四种授权模式+刷新令牌五种类型

security会在五个模式里边挑出一个然后授权的时候不是指定了grantType,根据grantType从五个模式中判断出一个来然后来生成最终的accesstoken

接着会判断grantType和当前的全局ganttype是否一致,重新读取了一下clientid等第三方应用信息,然后接下来最重要的是getAccessToken这个方法

tokenServices实际上就是AuthorizationServerTokenServices

然后这里再回顾一下流程图:

现在进入getOAuth2Authentication方法

这里不同的授权模式有不一样的实现类,由于我们当时传进来的是password,所以进的是这个ResourceOwnerPasswordTokenGranter

这里其实就是拿着我们请求的用户名密码封装成Authtication对象,然后传给AuthenticationManager做认证,在这个认证过程中实际上就会去调用我们之前写的UserDetailsService

到这里就已经获得了Authentication和OAuth2Request了,然后从调用链出去 再回到

再出去到TokenEndpoint

这个时候我们就已经得到了AccessToken了,接下去就是响应了~~~


愿你出走半生,归来仍是少年