前言
目前网上很多博客都在讲如何配置springsecurity oauth2.0,包括密码验证器的源码分析,授权码一般都是在讲如何获取验证码,没有深入**/oauth/token**端点详细跟进源码校验验证码并返回accessToken的过程

源码分析

AbstractEndpoint这个端点顶级父类有2个子类AuthorizationEndpoint和TokenEndpoint,其中AuthorizationEndpoint负责/oauth/authorize请求授权码,TokenEndpoint负责/oauth/token验证授权码颁发令牌

Spring Security源码分析 spring security oauth2 源码_spring boot


授权服务器配置使用jdbc保存验证,如何查询数据库验证授权码是否匹配的源码在后面会分析

Spring Security源码分析 spring security oauth2 源码_后端_02


使用post访问进入下面的方法

Spring Security源码分析 spring security oauth2 源码_spring_03


Spring Security源码分析 spring security oauth2 源码_spring_04


Spring Security源码分析 spring security oauth2 源码_java_05


查询到客户端信息后然后一直f8单步,封装tokenRequest传入下面的一个方法


因为我们使用的授权码方式,推测会根据授权类型调用授权码授权器,实际上是类似security的过滤器,挨个匹配,成功就返回,不继续执行

Spring Security源码分析 spring security oauth2 源码_spring boot_06


这里会根据grant_type匹配对应的授权器,使用私有构造器创建一个CompositeTokenGranter的委派类

Spring Security源码分析 spring security oauth2 源码_spring boot_07


调用

Spring Security源码分析 spring security oauth2 源码_后端_08


由于AuthorizationCodeTokenGranter extends AbstractTokenGranter ,AuthorizationCodeTokenGranter 并没有重写grant方法,实际上是调用了抽象类AbstractTokenGranter的grant方法获取access_token,里面调用了getOAuth2Authentication

Spring Security源码分析 spring security oauth2 源码_java_09


由于AuthorizationCodeTokenGranter重写了getOAuth2Authentication方法,所以进入到AuthorizationCodeTokenGranter 类的getOAuth2Authentication方法

Spring Security源码分析 spring security oauth2 源码_spring_10


获取code,到71行代码

Spring Security源码分析 spring security oauth2 源码_spring boot_11


因为我的授权码services配置的jdbc方式,所以到数据库查询授权码

Spring Security源码分析 spring security oauth2 源码_spring boot_12

如果为空,就会抛出异常返回,提示 Invalid authorization code:code

Spring Security源码分析 spring security oauth2 源码_后端_13


如果查询到记录,说明授权码第一次被使用,删除数据库的code,同时返回一个简单的OAuth2Authentication对象,里面只封装有授权码申请的时候的一些信息

Spring Security源码分析 spring security oauth2 源码_Spring Security源码分析_14


在查询用户的身份信息Authentication和OAuth2Request重新封装一个授权码认证(查询到code就算授权码认证通过)后OAuth2Authentication对象返回,tokenServices调用createAccessToken

拿着OAuth2Authentication对象去生成access_token,这里我配置的DefaultTokenServices

Spring Security源码分析 spring security oauth2 源码_后端_15


调用tokenStore,(这里我配置的 InMemoryTokenStore,可以换成redisTokenStore或者jwt的)首先根据OAuth2Authentication对象去内存获取token,是不是已经存在token对象,不存在进入下一步

Spring Security源码分析 spring security oauth2 源码_java_16


如果存在,验证是否过期,并删除存在的accessToken和refreshToken

然后创建refreshToken和accessToken,并以他们为key,OAuth2Authentication对象为value分别放入对应的并发map中

Spring Security源码分析 spring security oauth2 源码_spring boot_17


Spring Security源码分析 spring security oauth2 源码_后端_18


然后封装一个OAuth2AccessToken对象

Spring Security源码分析 spring security oauth2 源码_Spring Security源码分析_19


然后放入响应中去

Spring Security源码分析 spring security oauth2 源码_spring_20


下面就是我们在restClient看到的响应结果

Spring Security源码分析 spring security oauth2 源码_spring boot_21