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身份验证 。
文章插图
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虚拟机中的所有线程都使用相同的安全上下文 。
推荐阅读
- 严国华|《罚罪》唐绍文身份曝光,他确实是卧底,但并非听命于严国华
- 肖振邦|《罚罪》仅剩6集!肖振邦的结局注定悲惨,邱涛的真实身份即将暴露
- 浙江卫视|前浙江卫视主持人突然晒娃,曾和杨迪传绯闻,圈外丈夫仍身份成谜
- 李伯东|罚罪:李伯东真实身份曝光,与张秋峰联手上演碟中谍
- 章安仁|《流金岁月》,章安仁或许对蒋南孙有一丝喜欢,更爱的是她的身份
- 赵鹏超|《罚罪》最狠毒之人,为钱抛弃所有亲人,“大王”身份实至名归
- |探秘新钓点鱼影都没见到,却意外钩起一螃蟹,得知身份后高兴坏了
- 陆安然|覆流年:5000两买下的冬青身份不简单,陆安然既送了人情又得忠仆
- |40岁韩国男星染毒被逮!身份被网友找到了!
- 吴镇宇|吴镇宇:坐公交被指责不该坐老人座,无奈掏出身份证,引无限感慨