释迦牟尼的赛博生命
AI summary
本文主要介绍了 Spring Security 的认证功能,其中提到了 Spring Security 内置的多种认证协议,本文主要探讨了 Username and Password 的实现和使用。Spring Security 通过链式设计模式实现了这些认证协议,它们可以直接利用 SecurityContext 传递认证信息。对于认证,Spring Security 已经有一套设计好的架构了,实现认证只需要实现一些 class 即可。这篇文章详细介绍了认证的实现流程和代码,方便读者理解和实践。
Published
State
Unread
Tags
blog
码叔Blog
介绍
这一章主要内容是认证(验证身份),因为整个流程是先验证身份(你是谁?)了,再去授权(你能干什么?)。Spring Security 内置了很多认证协议实现,所以只探究 Username and Password 的实现和使用。
以下是 Spring Security 内置认证协议实现。
  • OAuth 2.0 Login - OAuth 2.0 Log In with OpenID Connect and non-standard OAuth 2.0 Login (i.e. GitHub)
Spring Security 框架很喜欢用(Filter)链式设计模式去实现这些认证协议,因为它们直接可以利用 SecurityContext 传递认证信息。
认证架构
对于认证,Spring Security 已经有一套设计好的架构了,实现认证其实只需要实现一些 class 即可。
notion image
上方图是 Spring Security 认证的基本流程,FilterChainPorxy 会根据 url 去匹配 SecurityFilterChain,默认情况下 Chain 包含AbstractAuthenticationProcessingFilter的实现。
AbstractAuthenticationProcessingFilter 是一个抽象的类,如果想定义一些认证规则可以实现这个类,其中里面有一个抽象方法attemptAuthentication() 由用户实现,然后被doFilter() 调用。
下面是经过删减的代码,用户实现attemptAuthentication() 的使用可以根据 request 获取请求参数,然后各种 if 比如密码是否正确等等流程,如果不匹配可以抛出一些异常,在 catch 的时候会调用异常处理器。
在实现attemptAuthentication() 的时候可以选择是否走认证管理器AuthenticationManager),这也是一些通用的抽象类只要配置或者实现一些接口就可以实现认证。如上图,首先会创建认证信息(Authentication),然后传输到认证管理器进行认证。
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { try { Authentication authenticationResult = attemptAuthentication(request, response); if (authenticationResult == null) { return; } successfulAuthentication(request, response, chain, authenticationResult); } catch (InternalAuthenticationServiceException failed) { unsuccessfulAuthentication(request, response, failed); } catch (AuthenticationException ex) { unsuccessfulAuthentication(request, response, ex); } }
下面看一下官方内置的 Username and Password 的实现。
notion image
UsernamePasswordAuthenticationFilter 是实现 AbstractAuthenticationProcessingFilter 对应的是 POST /login 请求(根据 request 判断是否使用这个过滤器)。
下方代码是 UsernamePasswordAuthenticationFilterattemptAuthentication() 方法实现,根据 request 获取 username 和 password 参数封装到认证信息Authentication(UsernamePasswordAuthenticationToken) 调用认证管理器进行认证。
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (this.postOnly && !request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } String username = obtainUsername(request); username = (username != null) ? username.trim() : ""; String password = obtainPassword(request); password = (password != null) ? password : ""; // 创建认证信息 UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); // 传输到认证管理器进行认证 return this.getAuthenticationManager().authenticate(authRequest); }
认证管理器默认使用 ProviderManager ,在身份验证的时候其实是调用AuthenticationProviderauthenticate() 方法,这个接口可以让用户实现不同的认证信息有不同的身份验证流程。
Username and Password 的默认实现是 DaoAuthenticationProvider ,各种判断后如果认证成功返回一个已认证的认证信息,否则会抛出异常。
Loading...
rail1dd
rail1dd
ENFJ|复古未来|跨界融合|自我探索
公告

评论相关

评论区邮箱填写qq数字邮箱即可抓取qq头像
网址部分为选填

数字学习

倒腾二进制世界的进程笔记,完全未入门级别,看一乐呵
毕竟属于基层和载体,找到合适自己的后也就没有大动过

风格认知

书影音游,整合在这,也不是想写月报,看心情

生存指南

如题,此处是更好的在现实世界生存下去的个人指南,本来想学学约翰·威尔逊的十万个怎么做,但本人似乎没那么跳脱,而且城市也不如纽约来得魔幻,so,这里都是一些超现实的shxt

城市漫游

取名来自文德斯的爱丽丝城市漫游记,所以梦想是真的能末路狂花,仗剑走天涯,但目前平淡的日常生活中也会偶尔出现一些奇妙体验,遂记录
*加密文章密码为同行人生日