Spring Security身份验证详细介绍

Spring Security提供了对身份验证的全面支持 。
架构组件下面描述Spring Security在Servlet身份验证中使用的主要架构组件 。

  • SecurityContextHolder:SecurityContextHolder是Spring Security存储身份验证的详细信息的地方 。
  • SecurityContext:从SecurityContextHolder中获取,包含当前认证用户的Authentication信息 。
  • Authentication:可以是AuthenticationManager的输入,以提供用户已提供的用于身份验证的凭据,也可以是来自SecurityContext的当前用户 。
  • GrantedAuthority:在Authentication上授予主体的授权(即角色、范围等) 。
  • AuthenticationManager:定义Spring Security的过滤器如何执行身份验证的API 。
  • ProviderManager:AuthenticationManager最常见的实现 。
  • AuthenticationProvider:由ProviderManager用于执行特定类型的身份验证 。
  • 使用AuthenticationEntryPoint请求凭证:用于客户端请求凭证(即重定向到一个登录页面,发送一个WWW-Authenticate响应,等等) 。
  • AbstractAuthenticationProcessingFilter:用于身份验证的基本过滤器 。这还可以很好地了解高层次的身份验证流程以及各个部分如何协同工作 。
身份验证机制
  • Username and Password:如何使用用户名/密码进行身份验证 。
  • OAuth 2.0 Login:OAuth 2.0登录使用OpenID连接和非标准的OAuth 2.0登录(例如GitHub) 。
  • SAML 2.0 Login:使用SAML 2.0登录 。
  • Central Authentication Server (CAS):支持CAS 。
  • Remember Me:如何记住用户会话过期 。
  • JAAS Authentication:使用JAAS进行身份验证 。
  • OpenID:OpenID身份验证(不要与OpenID Connect混淆) 。
  • Pre-Authentication ScenarIOS:使用外部机制(如SiteMinder或JAVA EE安全性)进行身份验证,但仍然使用Spring security进行授权和保护,以防止常见攻击 。
  • X509 Authentication:X509身份验证 。
SecurityContextHolderSpring Security的身份验证模型的核心是SecurityContextHolder 。它包含SecurityContext 。
Spring Security身份验证详细介绍

文章插图
SecurityContextHolder介绍
SecurityContextHolder是Spring Security存储身份验证的详细信息的地方 。Spring Security并不关心SecurityContextHolder是如何填充的 。如果它包含一个值,那么它就被用作当前经过身份验证的用户 。
指定用户身份验证的最简单方法是直接设置SecurityContextHolder 。
示例:设置SecurityContextHolder
SecurityContext context = SecurityContextHolder.createEmptyContext(); Authentication authentication =new TestingAuthenticationToken("username", "password", "ROLE_USER"); context.setAuthentication(authentication);SecurityContextHolder.setContext(context); 我们首先创建一个空的SecurityContext 。
重要的是要创建一个新的SecurityContext实例,而不是使用
SecurityContextHolder.getContext().setAuthentication(authentication),以避免多线程之间的竞争条件 。
接下来,我们创建一个新的Authentication对象 。
Spring Security并不关心在SecurityContext上设置了什么类型的Authentication实现 。
这里我们使用
TestingAuthenticationToken,因为它非常简单 。更常见的生产场景是UsernamePasswordAuthenticationToken(userDetails, password, authorities) 。
最后,我们在SecurityContextHolder上设置SecurityContext 。
Spring Security将使用此信息进行授权 。
如果希望获得关于经过身份验证的主体的信息,可以通过访问SecurityContextHolder来实现 。
示例:访问当前认证用户
SecurityContext context = SecurityContextHolder.getContext();Authentication authentication = context.getAuthentication();String username = authentication.getName();Object principal = authentication.getPrincipal();Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();默认情况下,SecurityContext使用ThreadLocal来存储这些详细信息,这意味着SecurityContext对于同一个线程中的方法总是可用的,即使SecurityContext没有显式地作为参数传递给这些方法 。以这种方式使用ThreadLocal是相当安全的,如果在处理当前主体的请求后小心地清除线程 。Spring Security的FilterChainProxy确保SecurityContext总是被清除 。
有些应用程序并不完全适合使用ThreadLocal,因为它们处理线程的特定方式 。例如,Swing客户机可能希望Java虚拟机中的所有线程都使用相同的安全上下文 。


推荐阅读