回顾之前文章:
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。
SpringSecurity OAuth2 认证流程

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

被折叠的 条评论
为什么被折叠?



