SpringSecurity中文文档—Authentication—Session Management

8 篇文章 1 订阅
6 篇文章 1 订阅

Detecting Timeouts

您可以将Spring Security配置为检测无效会话ID的提交,并将用户重定向到适当的URL。这是通过会话管理元素实现的:

@Override
protected void configure(HttpSecurity http) throws Exception{
    http
        .sessionManagement(session -> session
            .invalidSessionUrl("/invalidSession.htm")
        );
}

请注意,如果使用此机制检测会话超时,如果用户注销,然后在不关闭浏览器的情况下重新登录,则可能会错误地报告错误。这是因为当您使会话无效时,会话cookie不会被清除,即使用户已注销,也会重新提交。您可以在注销时显式删除JSESSIONID cookie,例如,在注销处理程序中使用以下语法:

@Override
protected void configure(HttpSecurity http) throws Exception{
    http
        .logout(logout -> logout
            .deleteCookies("JSESSIONID")
        );
}

不幸的是,这不能保证适用于每个servlet容器,所以您需要在您的环境中测试它。
如果您在代理后运行应用程序,还可以通过配置代理服务器删除会话cookie。例如,使用Apache HTTPD的mod_头,下面的指令将删除JSESSIONID cookie,方法是在响应注销请求时使其过期(假设应用程序部署在路径/教程下):

<LocationMatch "/tutorial/logout">
Header always set Set-Cookie "JSESSIONID=;Path=/tutorial;Expires=Thu, 01 Jan 1970 00:00:00 GMT"
</LocationMatch>

Concurrent Session Control

如果您希望限制单个用户登录应用程序的能力,Spring Security通过以下简单的添加来支持这种开箱即用的功能。首先,您需要将以下侦听器添加到配置中,以保持Spring Security更新会话生命周期事件:

@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
    return new HttpSessionEventPublisher();
}

然后将以下行添加到application context中:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .sessionManagement(session -> session
            .maximumSessions(1)
        );
}

这将防止用户多次登录——第二次登录将导致第一次登录无效。通常情况下,您希望阻止第二次登录,在这种情况下,您可以使用:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .sessionManagement(session -> session
            .maximumSessions(1)
            .maxSessionsPreventsLogin(true)
        );
}

第二次登录将被拒绝。“拒绝”的意思是,如果使用基于表单的登录,用户将被发送到身份验证失败url。如果第二次身份验证是通过另一个非交互机制进行的,例如“记住我”,则会向客户端发送一个“未经授权”(401)错误。如果您想使用错误页面,可以将属性session-authentication-error- url添加到session management元素中。
如果要使用自定义的身份验证过滤器进行基于表单的登录,则必须显式配置并发会话控制支持。有关更多详细信息,请参阅会话管理一章。

Session Fixation Attack Protection

会话固定攻击是一种潜在风险,恶意攻击者可以通过访问站点创建会话,然后说服其他用户使用同一会话登录(例如,通过向他们发送包含会话标识符作为参数的链接)。Spring Security通过创建新会话或在用户登录时更改会话ID来自动防止这种情况。如果不需要此保护,或者它与其他要求冲突,则可以使用上的session-fixation-protection属性来控制行为,该属性有四个选项:

  • none :不做任何事情,保留原会话。
  • newSession:创建一个新的“干净”会话,而不复制现有会话数据(Spring安全相关属性仍将被复制)。
  • migrateSession :创建一个新会话,并将所有现有会话属性复制到新会话。这是Servlet 3.0或更早版本容器中的默认值。
  • changeSessionId :不要创建新会话。相反,使用Servlet容器HttpServletRequest#changeSessionId()提供的会话固定保护。此选项仅在Servlet 3.1(Java EE 7)和更新的容器中可用。在旧容器中指定它将导致异常。这是Servlet 3.1和更新的容器中的默认值。
    当会话固定保护发生时,会导致在应用程序上下文中发布SessionFixationProtectionEvent。如果使用changeSessionId,这种保护也会导致任何javax.servlet.http.HttpSessionIdListeners收到通知,因此如果代码同时侦听这两个事件,请小心。有关更多信息,请参阅会话管理一章。

SessionManagementFilter

SessionManagementFilter根据SecurityContextHolder的当前内容检查SecurityContextRepository的内容,以确定用户在当前请求期间是否已通过身份验证,通常是通过非交互式身份验证机制,如预验证或记住我[1]。如果存储库包含security context,则filter 不执行任何操作。如果没有,并且 thread-local SecurityContext包含一个(non-anonymous)身份验证对象,则过滤器会假定它们已被堆栈中的前一个过滤器身份验证。然后,它将调用已配置的SessionAuthenticationStrategy。
如果用户当前未通过身份验证,筛选器将检查是否已请求过的无效会话ID(例如,由于超时),并将调用配置的InvalidSessionStrategy(如果已设置)。最常见的行为就是重定向到一个固定的URL,这被封装在标准实现SimpleDirectInvalidSessionStrategy中。如前所述,在通过命名空间配置无效会话URL时,也会使用后者。

SessionAuthenticationStrategy

SessionAuthenticationStrategy由SessionManagementFilter和AbstractAuthenticationProcessingFilter使用,因此,如果您使用的是自定义表单登录类,则需要将其注入这两个类中。在本例中,将名称空间和自定义bean组合在一起的典型配置可能如下所示:

<http>
<custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" />
<session-management session-authentication-strategy-ref="sas"/>
</http>

<beans:bean id="myAuthFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
	<beans:property name="sessionAuthenticationStrategy" ref="sas" />
	...
</beans:bean>

<beans:bean id="sas" class=
"org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />

Concurrency Control

Spring Security能够防止主体对同一应用程序进行超过指定次数的并发身份验证。许多ISV利用这一点来实施许可,而网络管理员喜欢这一功能,因为它有助于防止人们共享登录名。例如,您可以阻止用户“蝙蝠侠”从两个不同的会话登录到web应用程序。您可以终止他们以前的登录,也可以在他们再次尝试登录时报告错误,从而阻止第二次登录。请注意,如果使用第二种方法,未明确注销(例如,刚刚关闭浏览器)的用户将无法再次登录,直到其原始会话过期。
namespace支持并发控制,因此请查看前面的namespace章节以了解最简单的配置。不过有时候你需要定制一些东西。
该实现使用了SessionAuthenticationStrategy的专用版本,称为ConcurrentSessionControlAuthenticationStrategy。
以前,并发身份验证检查是由ProviderManager进行的,它可以注入ConcurrentSessionController。后者将检查用户是否试图超过允许的会话数。然而,这种方法要求提前创建HTTP会话,这是不可取的。在Spring Security 3中,用户首先由AuthenticationManager进行身份验证,一旦他们成功通过身份验证,就会创建一个会话,并检查是否允许他们打开另一个会话。
要使用并发会话支持,您需要将以下内容添加到web.xml:

<listener>
	<listener-class>
	org.springframework.security.web.session.HttpSessionEventPublisher
	</listener-class>
</listener>

此外,还需要将ConcurrentSessionFilter添加到FilterChainProxy。ConcurrentSessionFilter需要两个构造函数参数:sessionRegistry(通常指向SessionRegistryImpl的实例)和SessionInformation ExpiredStrategy(定义会话过期时应用的策略)。使用namespace创建FilterChainProxy和其他默认bean的配置可能如下所示:

<http>
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" />

<session-management session-authentication-strategy-ref="sas"/>
</http>

<beans:bean id="redirectSessionInformationExpiredStrategy"
class="org.springframework.security.web.session.SimpleRedirectSessionInformationExpiredStrategy">
<beans:constructor-arg name="invalidSessionUrl" value="/session-expired.htm" />
</beans:bean>

<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<beans:constructor-arg name="sessionInformationExpiredStrategy" ref="redirectSessionInformationExpiredStrategy" />
</beans:bean>

<beans:bean id="myAuthFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>

<beans:bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<beans:constructor-arg>
	<beans:list>
	<beans:bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
		<beans:constructor-arg ref="sessionRegistry"/>
		<beans:property name="maximumSessions" value="1" />
		<beans:property name="exceptionIfMaximumExceeded" value="true" />
	</beans:bean>
	<beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
	</beans:bean>
	<beans:bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
		<beans:constructor-arg ref="sessionRegistry"/>
	</beans:bean>
	</beans:list>
</beans:constructor-arg>
</beans:bean>

<beans:bean id="sessionRegistry"
	class="org.springframework.security.core.session.SessionRegistryImpl" />

将listener添加到web.xml使ApplicationEvent在每次HttpSession开始或结束时发布到Spring ApplicationContext。这很关键,因为它允许在会话结束时通知SessionRegistryImpl。如果没有它,用户将永远无法在超过会话许可后再次登录,即使他们退出另一个会话或会话超时。

Querying the SessionRegistry for currently authenticated users and their sessions

通过namespace或使用普通bean设置并发控制有一个有用的副作用,即为您提供对SessionRegistry的引用,您可以直接在应用程序中使用该引用,因此即使您不想限制用户可能拥有的会话数,无论如何,建立基础设施可能是值得的。可以将maximumSession属性设置为-1以允许无限会话。如果您使用的是namespace,那么可以使用session-registry-alias属性为内部创建的SessionRegistry设置别名,从而提供一个可以注入到自己bean中的引用。
getAllPrinciples()方法为您提供当前经过身份验证的用户的列表。可以通过调用getAllSessions(Object principal,boolean includeExpiredSessions)方法列出用户的会话,该方法返回会话信息对象的列表。还可以通过在SessionInformation实例上调用expireNow()使用户的会话过期。当用户返回应用程序时,他们将无法继续。例如,您可能会发现这些方法在管理应用程序中很有用。有关更多信息,请查看Javadoc。
SessionManagementFilter不会检测到通过在身份验证后执行重定向(例如表单登录)的机制进行的身份验证,因为在身份验证请求期间不会调用filter 。在这些情况下,会话管理功能必须单独处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security-3.0.1 中文官方文档(翻译版) 这次发布的Spring Security-3.0.1 是一个bug fix 版,主要是对3.0 中存在的一些问题进 行修 正。文档中没有添加新功能的介绍,但是将之前拼写错误的一些类名进行了修正,建议开发 者以这一版本的文档为参考。 另:Spring Security 从2010-01-01 以后,版本控制从SVN 换成了GIT,我们在翻译文档的 时候,主要是根据SVN 的变化来进行文档内容的比对,这次换成GIT 后,感觉缺少了之前 那种文本比对工具,如果有对GIT 熟悉的朋友,还请推荐一下文本比对的工具,谢谢。 序言 I. 入门 1. 介绍 1.1. Spring Security 是什么? 1.2. 历史 1.3. 发行版本号 1.4. 获得Spring Security 1.4.1. 项目模块 1.4.1.1. Core - spring-security-core.jar 1.4.1.2. Web - spring-security-web.jar 1.4.1.3. Config - spring-security-config.jar 1.4.1.4. LDAP - spring-security-ldap.jar 1.4.1.5. ACL - spring-security-acl.jar 1.4.1.6. CAS - spring-security-cas-client.jar 1.4.1.7. OpenID - spring-security-openid.jar 1.4.2. 获得源代码 2. Security 命名空间配置 2.1. 介绍 2.1.1. 命名空间的设计 2.2. 开始使用安全命名空间配置 2.2.1. 配置web.xml 2.2.2. 最小 配置 2.2.2.1. auto-config 包含了什么? 2.2.2.2. 表单和基本登录选项 2.2.3. 使用其他认证提供器 2.2.3.1. 添加一个密码编码器 2.3. 高级web 特性 2.3.1. Remember-Me 认证 2.3.2. 添加HTTP/HTTPS 信道安全 2.3.3. 会话管理 2.3.3.1. 检测超时 2.3.3.2. 同步会话控制 2.3.3.3. 防止Session 固定攻击 2.3.4. 对OpenID 的支持 2.3.4.1. 属性交换 2.3.5. 添加你自己的filter 2.3.5.1. 设置自定义AuthenticationEntryPoint 2.4. 保护方法 2.4.1. 元素 2.4.1.1. 使用protect-pointcut 添加安全切点 2.5. 默认的AccessDecisionManager 2.5.1. 自定义AccessDecisionManager 2.6. 验证管理器和命名空间 3. 示例程序 3.1. Tutorial 示例 3.2. Contacts 3.3. LDAP 例子 3.4. CAS 例子 3.5. Pre-Authentication 例子 4. Spring Security 社区 4.1. 任务跟踪 4.2. 成为参与者 4.3. 更多信息 II. 结构和实现 5. 技术概述 5.1. 运行环境 5.2. 核心组件 5.2.1. SecurityContextHolder, SecurityContext 和Authentication 对象 5.2.1.1. 获得当前用户的信息 5.2.2. UserDetailsService 5.2.3. GrantedAuthority 5.2.4. 小结 5.3. 验证 5.3.1. 什么是Spring Security 的验证呢? 5.3.2. 直接设置SecurityContextHolder 的内容 5.4. 在web 应用中验证 5.4.1. ExceptionTranslationFilter 5.4.2. AuthenticationEntryPoint 5.4.3. 验证机制 5.4.4. 在请求之间保存SecurityContext 。 5.5. Spring Security 中的访问控制(验证) 5.5.1. 安全和AOP 建议 5.5.2. 安全对象和AbstractSecurityInterceptor 5.5.2.1. 配置属性是什么? 5.5.2.2. RunAsManager 5.5.2.3. AfterInvocationManager 5.5.2.4. 扩展安全对象模型 5.6. 国际化 6. 核心服务 6.1. The AuthenticationManager , ProviderManager 和AuthenticationProvider s 6.1.1. DaoAuthenticationProvider 6.2. UserDetailsService 实现 6.2.1. 内存认证 6.2.2. JdbcDaoImpl 6.2.2.1. 权限分组 6.3. 密码加密 6.3.1. 什么是散列加密? 6.3.2. 为散列加点儿盐 6.3.3. 散列和认证 III. web 应用安全 7. 安全过滤器链 7.1. DelegatingFilterProxy 7.2. FilterChainProxy 7.2.1. 绕过过滤器链 7.3. 过滤器顺序 7.4. 使用其他过滤器—— 基于框架 8. 核心安全过滤器 8.1. FilterSecurityInterceptor 8.2. ExceptionTranslationFilter 8.2.1. AuthenticationEntryPoint 8.2.2. AccessDeniedHandler 8.3. SecurityContextPersistenceFilter 8.3.1. SecurityContextRepository 8.4. UsernamePasswordAuthenticationFilter 8.4.1. 认证成功和失败的应用流程 9. Basic(基本)和Digest(摘要)验证 9.1. BasicAuthenticationFilter 9.1.1. 配置 9.2. DigestAuthenticationFilter 9.2.1. Configuration 10. Remember-Me 认证 10.1. 概述 10.2. 简单基于散列标记的方法 10.3. 持久化标记方法 10.4. Remember-Me 接口和实现 10.4.1. TokenBasedRememberMeServices 10.4.2. PersistentTokenBasedRememberMeServices 11. 会话管理 11.1. SessionManagementFilter 11.2. SessionAuthenticationStrategy 11.3. 同步会话 12. 匿名认证 12.1. 概述 12.2. 配置 12.3. AuthenticationTrustResolver IV. 授权 13. 验证架构 13.1. 验证 13.2. 处理预调用 13.2.1. AccessDecisionManager 13.2.2. 基于投票的AccessDecisionManager 实现 13.2.2.1. RoleVoter 13.2.2.2. AuthenticatedVoter 13.2.2.3. Custom Voters 13.3. 处理后决定 14. 安全对象实现 14.1. AOP 联盟(MethodInvocation) 安全拦截器 14.1.1. 精确的MethodSecurityIterceptor 配置 14.2. AspectJ (JoinPoint) 安全拦截器 15. 基于表达式的权限控制 15.1. 概述 15.1.1. 常用内建表达式 15.2. Web 安全表达式 15.3. 方法安全表达式 15.3.1. @Pre 和@Post 注解 15.3.1.1. 访问控制使用@PreAuthorize 和@PostAuthorize 15.3.1.2. 过滤使用@PreFilter 和@PostFilter 16. acegi 到spring security 的转换方式 16.1. Spring Security 是什么 16.2. 目标 16.3. 步骤 16.4. 总结 V. 高级话题 17. 领域对象安全(ACLs) 17.1. 概述 17.2. 关键概念 17.3. 开始 18. 预认证场景 18.1. 预认证框架类 18.1.1. AbstractPreAuthenticatedProcessingFilter 18.1.2. AbstractPreAuthenticatedAuthenticationDetailsSource 18.1.2.1. J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource 18.1.3. PreAuthenticatedAuthenticationProvider 18.1.4. Http403ForbiddenEntryPoint 18.2. 具体实现 18.2.1. 请求头认证(Siteminder) 18.2.1.1. Siteminder 示例配置 18.2.2. J2EE 容器认证 19. LDAP 认证 19.1. 综述 19.2. 在Spring Security 里使用LDAP 19.3. 配置LDAP 服务器 19.3.1. 使用嵌入测试服务器 19.3.2. 使用绑定认证 19.3.3. 读取授权 19.4. 实现类 19.4.1. LdapAuthenticator 实现 19.4.1.1. 常用功能 19.4.1.2. BindAuthenticator 19.4.1.3. PasswordComparisonAuthenticator 19.4.1.4. 活动目录认证 19.4.2. 链接到LDAP 服务器 19.4.3. LDAP 搜索对象 19.4.3.1. FilterBasedLdapUserSearch 19.4.4. LdapAuthoritiesPopulator 19.4.5. Spring Bean 配置 19.4.6. LDAP 属性和自定义UserDetails 20. JSP 标签库 20.1. 声明Taglib 20.2. authorize 标签 20.3. authentication 标签 20.4. accesscontrollist 标签 21. Java 认证和授权服务(JAAS)供应器 21.1. 概述 21.2. 配置 21.2.1. JAAS CallbackHandler 21.2.2. JAAS AuthorityGranter 22. CAS 认证 22.1. 概述 22.2. CAS 是如何工作的 22.3. 配置CAS 客户端 23. X.509 认证 23.1. 概述 23.2. 把X.509 认证添加到你的web 系统中 23.3. 为tomcat 配置SSL 24. 替换验证身份 24.1. 概述 24.2. 配置 A. 安全数据库表结构 A.1. User 表 A.1.1. 组权限 A.2. 持久登陆(Remember-Me)表 A.3. ACL 表 A.3.1. Hypersonic SQL A.3.1.1. PostgreSQL B. 安全命名空间 B.1. Web 应用安全- 元素 B.1.1. 属性 B.1.1.1. servlet-api-provision B.1.1.2. path-type B.1.1.3. lowercase-comparisons B.1.1.4. realm B.1.1.5. entry-point-ref B.1.1.6. access-decision-manager-ref B.1.1.7. access-denied-page B.1.1.8. once-per-request B.1.1.9. create-session B.1.2. B.1.3. 元素 B.1.3.1. pattern B.1.3.2. method B.1.3.3. access B.1.3.4. requires-channel B.1.3.5. filters B.1.4. 元素 B.1.5. 元素 B.1.5.1. login-page B.1.5.2. login-processing-url B.1.5.3. default-target-url B.1.5.4. always-use-default-target B.1.5.5. authentication-failure-url B.1.5.6. authentication-success-handler-ref B.1.5.7. authentication-failure-handler-ref B.1.6. 元素 B.1.7. 元素 B.1.7.1. data-source-ref B.1.7.2. token-repository-ref B.1.7.3. services-ref B.1.7.4. token-repository-ref B.1.7.5. key 属性 B.1.7.6. token-validity-seconds B.1.7.7. user-service-ref B.1.8. 元素 B.1.8.1. session-fixation-protection B.1.9. 元素 B.1.9.1. max-sessions 属性 B.1.9.2. expired-url 属性 B.1.9.3. error-if-maximum-exceeded 属性 B.1.9.4. session-registry-alias 和session-registry-ref 属性 B.1.10. 元素 B.1.11. 元素 B.1.11.1. subject-principal-regex 属性 B.1.11.2. user-service-ref 属性 B.1.12. 元素 B.1.13. 元素 B.1.13.1. logout-url 属性 B.1.13.2. logout-success-url 属性 B.1.13.3. invalidate-session 属性 B.1.14. 元素 B.2. 认证服务 B.2.1. 元素 B.2.1.1. 元素 B.2.1.2. 使用 来引用一个AuthenticationProvider Bean B.3. 方法安全 B.3.1. 元素 B.3.1.1. secured-annotations 和jsr250-annotations 属性 B.3.1.2. 安全方法使用 B.3.1.3. 元素 B.3.2. LDAP 命名空间选项 B.3.2.1. 使用 元素定义LDAP 服务器 B.3.2.2. 元素 B.3.2.3. 元素

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值