在多个服务器上使用 Spring Security 和 Spring Redis Session
Posted
技术标签:
【中文标题】在多个服务器上使用 Spring Security 和 Spring Redis Session【英文标题】:Using Spring Security and Spring Redis Session on multiple servers 【发布时间】:2015-09-01 14:59:39 【问题描述】:我有一个 spring 项目,并且刚刚添加了带有 redis 数据存储的 spring session 来保存 session 对象。它已经将 sring 安全用于页面权限等。导入已更新为使用 spring 4.1.6。和安全 4.0.1。
目前正在使用基于 xml 的配置。我已经设置好了,所以 spring session 过滤器在 spring security filter 之前
<!-- Spring session filters -->
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- security filters -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
进入登录页面后,正如预期的那样,有一个 cookie。一个新的“会话”cookie,与 redis 中的 cookie 相关联。但是在登录时,会创建原始的 JSESSIONID cookie,这不会保留在 redis 数据库中。这个cookie是必需的,好像我把它设置为'stateless'然后系统就不会登录了。
这意味着在 UI 的多个实例上,服务器之间会有不同的安全会话,从而使 redis 数据存储变得冗余。
我目前不确定是否需要 JSESSIONID,因为登录时大多数字段都放在 SESSION 中。在检索用户等时使用正确的 SESSION cookie,并且相同的 cookie 用于保存信息。除了出于安全原因之外,是否有人能够解释它的必要性。
有没有办法将 JSESSIONID 也保存在数据库中,或者将安全会话中的信息保存在普通的 SESSION cookie 中。
【问题讨论】:
【参考方案1】:问题是在添加 spring 会话过滤器之前设置了请求上下文。解决方案是在设置 requestContext 时显式设置,所以是在 spring 会话之后。
<!-- Spring session filters -->
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Request context filter - has to be after session so replaces the jsessionid with correct session -->
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这需要在WEB-INF的web.xml中添加
【讨论】:
以上是关于在多个服务器上使用 Spring Security 和 Spring Redis Session的主要内容,如果未能解决你的问题,请参考以下文章
Spring security OAuth中的多个资源服务器配置
如何从多个服务器获取与 Spring Security 和 Spring Session 相同的会话
Spring Security:针对多个 LDAP 服务器和基于 DAO 的身份验证进行身份验证
Spring Security - 多个会话取决于使用情况(登录/httpBasic)
Spring Security 具有不同用户详细信息的多个 HTTPSecurity 服务在 Spring Boot 中不起作用