前言
目前网上很多博客都在讲如何配置springsecurity oauth2.0,包括密码验证器的源码分析,授权码一般都是在讲如何获取验证码,没有深入**/oauth/token**端点详细跟进源码校验验证码并返回accessToken的过程
源码分析
AbstractEndpoint这个端点顶级父类有2个子类AuthorizationEndpoint和TokenEndpoint,其中AuthorizationEndpoint负责/oauth/authorize请求授权码,TokenEndpoint负责/oauth/token验证授权码颁发令牌
授权服务器配置使用jdbc保存验证,如何查询数据库验证授权码是否匹配的源码在后面会分析
使用post访问进入下面的方法
查询到客户端信息后然后一直f8单步,封装tokenRequest传入下面的一个方法
因为我们使用的授权码方式,推测会根据授权类型调用授权码授权器,实际上是类似security的过滤器,挨个匹配,成功就返回,不继续执行
这里会根据grant_type匹配对应的授权器,使用私有构造器创建一个CompositeTokenGranter的委派类
调用
由于AuthorizationCodeTokenGranter extends AbstractTokenGranter ,AuthorizationCodeTokenGranter 并没有重写grant方法,实际上是调用了抽象类AbstractTokenGranter的grant方法获取access_token,里面调用了getOAuth2Authentication
由于AuthorizationCodeTokenGranter重写了getOAuth2Authentication方法,所以进入到AuthorizationCodeTokenGranter 类的getOAuth2Authentication方法
获取code,到71行代码
因为我的授权码services配置的jdbc方式,所以到数据库查询授权码
如果为空,就会抛出异常返回,提示 Invalid authorization code:code
如果查询到记录,说明授权码第一次被使用,删除数据库的code,同时返回一个简单的OAuth2Authentication对象,里面只封装有授权码申请的时候的一些信息
在查询用户的身份信息Authentication和OAuth2Request重新封装一个授权码认证(查询到code就算授权码认证通过)后OAuth2Authentication对象返回,tokenServices调用createAccessToken
拿着OAuth2Authentication对象去生成access_token,这里我配置的DefaultTokenServices
调用tokenStore,(这里我配置的 InMemoryTokenStore,可以换成redisTokenStore或者jwt的)首先根据OAuth2Authentication对象去内存获取token,是不是已经存在token对象,不存在进入下一步
如果存在,验证是否过期,并删除存在的accessToken和refreshToken
然后创建refreshToken和accessToken,并以他们为key,OAuth2Authentication对象为value分别放入对应的并发map中
然后封装一个OAuth2AccessToken对象
然后放入响应中去
下面就是我们在restClient看到的响应结果