springcloud — 微服务鉴权管理Spring Security OAuth2原理解析(四)

SpringSecurity OAuth2 认证流程
本文深入解析了SpringSecurity OAuth2的认证流程,特别是客户端模式下的Token生成过程。从AuthorizationServerConfigurerAdapter配置类开始,逐步介绍了ClientCredentialsTokenEndpointFilter、AuthenticationManager等组件的工作原理。

回顾之前文章:
1. 微服务鉴权管理之OAuth2原理解析(一)
2. 微服务鉴权管理Spring Security原理解析(二)
3. 微服务鉴权管理Spring Security OAuth2原理解析(三)
本文开始从源码的层面,讲解一些Spring Security Oauth2的认证流程。

1、AuthorizationServerConfigurerAdapter

上一篇博客中我们尝试使用了password模式和client模式,有一个比较关键的endpoint:/oauth/token。从这个入口开始分析,spring security oauth2内部是如何生成token的。获取token,与第一篇文章中的两个重要概念之一有关,也就是AuthorizationServer与ResourceServer中的AuthorizationServer。

在之前的配置中:

@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
   
   }

出现了AuthorizationServerConfigurerAdapter 关键类,他关联了三个重要的配置类,分别是:

public class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer {
   
   
	//配置AuthorizationServer安全认证的相关信息,
	//创建ClientCredentialsTokenEndpointFilter核心过滤器
	@Override
	public void configure(AuthorizationServerSecurityConfigurer security) throws Exception{
   
   
	}
	//配置OAuth2的客户端相关信息
	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
   
   
	}
	// 配置AuthorizationServerEndpointsConfigurer众多相关类,
	// 包括配置身份认证器,配置认证方式,TokenStore,TokenGranter,OAuth2RequestFactory
	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints <3>) throws Exception {
   
   
	}

}
2、客户端身份认证核心过滤器ClientCredentialsTokenEndpointFilter

截取关键的代码,可以分析出大概的流程 在请求到达/oauth/token之前经过了ClientCredentialsTokenEndpointFilter这个过滤器,关键方法如下:

public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
		throws AuthenticationException, IOException, ServletException {
   
   
	...
	String clientId = request.getParameter("client_id");
	String clientSecret = request.getParameter("client_secret");

	...
	clientId = clientId.trim();
	UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId,
			clientSecret);

	return this.getAuthenticationManager().authenticate(authRequest);

}
3、顶级身份管理者AuthenticationManager

用来从请求中获取client_id,client_secret,组装成一个UsernamePasswordAuthenticationToken作为身份标识,使用容器中的顶级身份管理器AuthenticationManager去进行身份认证(AuthenticationManager的实现类一般是ProviderManager。而ProviderManager内部维护了一个List,真正的身份认证是由一系列AuthenticationProvider去完成。而AuthenticationProvider的常用实现类则是DaoAuthenticationProvider,DaoAuthenticationProvider内部又聚合了一个UserDetailsService接口,UserDetailsService才是获取用户详细信息的最终接口,而我们上一篇文章中在内存中配置用户,就是使用了UserDetailsService的一个实现类InMemoryUserDetailsManager)。UML类图可以大概理解下这些类的关系,省略了授权部分。
在这里插入图片描述
前面一篇文章已经提到了client模式是不存在“用户”的概念的,那么这里的身份认证是在认证什么呢?debug可以发现UserDetailsService的实现被适配成了ClientDetailsUserDetailsService,这个设计是将client客户端的信息(client_id,client_secret)适配成用户的信息(username,password),这样我们的认证流程就不需要修改了。

经过ClientCredentialsTokenEndpointFilter之后,身份信息已经得到了AuthenticationManager的验证。接着便到达了TokenEndpoint。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RachelHwang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值