Spring Security Oauth2.0的请求流程分析

好多年没有接触oauth2.0,最近接手一个老项目,项目扩展了手机号密码登录、手机号验证码登录多重认证,遇到一些问题,大概梳理一下过程

开发环境

spring-security-oauth2 2.3.4.RELEASE版本
spring-security-web 5.3.9.RELEASE版本

获取token接口

获取token

POST /oauth/token?grant_type=phone_sms
application/form-data
Authorization: Basic d3g6d3g=
参数:
phone=xxx
smsCode=xxx

刷新token

POST  /oauth/token?grant_type=refresh_token&refresh_token=134afb26-6491-479c-9edb-cb603f86dcd2
Authorization: Basic d3g6d3g=

认证过程

Basic认证

org.springframework.security.web.authentication.www.BasicAuthenticationFilter#doFilterInternal拦截Authorization请求头
在这里插入图片描述

匿名认证/token认证

authenticationConverter.convert根据request请求头header获取Authorition: Basic请求头
这一步如果获取的authRequest=null(不存在Authorization头;Authorization头不是Basic认证),则进入filterChain进行校验,所以匿名认证、bearer认证都会走这一步
核心类在org.springframework.security.web.access.intercept.FilterSecurityInterceptor#doFilter, 处理逻辑在父类中处理
在这里插入图片描述
1). authenticateIfRequired方法尝试用户认证,进入authenticationManager.authenticate(authentication)方法获取认证,真正的认证是在org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager#authenticate中进行
在这里插入图片描述
2). 回到AbstractSecurityInterceptor类中的accessDecisionManager.decide(authenticated, object, attributes)方法,在方法org.springframework.security.access.vote.AffirmativeBased#decide中如果校验失败,直接抛出401异常
在这里插入图片描述

Basic认证

1). 调用Authentication authResult = this.authenticationManager.authenticate(authRequest);进行client认证,在实现类中org.springframework.security.authentication.ProviderManager#authenticate获取client登录信息
在这里插入图片描述
可以看到这里有两个provider,使用DaoAuthenticationProvider实现类retrieveUser方法获取client信息 。这一步也有一个**[扩展点2]**
在这里插入图片描述
最终在ClientDetailsUserDetailsService#loadUserByUsername中根据Basic中信息校验并获取client信息。这一步也有一个**[扩展点3]**
在这里插入图片描述
至此也就获取到了详细的clientDetails信息,也就是在AuthorizationServerConfigurerAdapter#configure(org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer)实现方法中通过client.inMemory()中定义的client信息,这里既可以是InMemory存储,也可以是Jdbc存储。
2). 完成client认证后进入生成token阶段
进入org.springframework.security.oauth2.provider.endpoint.TokenEndpoint#postAccessToken,进行一系列的校验、组装参数,通过granter去获取token ** [扩展点4]**
在这里插入图片描述
这一步非常关键,可以看到ImplicitClientCredentials认证模式,还有PhoneSmsCustom自定义模式,RefreshToken也在这里处理
在这里插入图片描述
又看到CompositeTokenGranter类,这里使用到策略模型根据不同的grant_type使用不同的granter校验用户获取用户信息,可以看到AbstractTokenGranter的实现 [扩展点5]
在这里插入图片描述
最后一步org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getAccessToken获取token进行持久化存储
在这里插入图片描述
如果采用redis缓存token的话,也可以在redis中看到为什么会存储很多的token
在这里插入图片描述

扩展点

  1. 扩展点1:
  2. 扩展点2:provider扩展,重写DaoAuthenticationProvider类,例如:DecodePwdAuthenticationProvider
  3. 扩展点3:UserServiceDetails扩展,默认情况下只有一个默认方法UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;,这一步可以扩展不同的方法给granter使用
  4. 扩展点4:granter扩展,继承AbstractTokenGranter类,实现策略模型,根据不同的granter实现不同的用户校验逻辑。例如: PhoneSmsCustomTokenGranter
  5. 扩展点5:重写AbstractTokenGranter类的getOAuth2Authentication,调用UserServiceDetails的实现方法获取用户数据,生成OAuth2Authentication用户认证。例如:AbstractCustomTokenGranter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值