在多个服务器上使用 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 OAuth2 深入解析

Spring security OAuth中的多个资源服务器配置

如何从多个服务器获取与 Spring Security 和 Spring Session 相同的会话

Spring Security:针对多个 LDAP 服务器和基于 DAO 的身份验证进行身份验证

Spring Security - 多个会话取决于使用情况(登录/httpBasic)

Spring Security 具有不同用户详细信息的多个 HTTPSecurity 服务在 Spring Boot 中不起作用