Spring security 如何使用Spring会话+;Spring安全xml配置和多重安全过滤器 背景

Spring security 如何使用Spring会话+;Spring安全xml配置和多重安全过滤器 背景,spring-security,spring-session,spring-data-redis,Spring Security,Spring Session,Spring Data Redis,大家好, 我们有一个Spring项目,它使用Spring安全性。我们通过定义 <b:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> 而且一切都很好:)。现在,根据doc下一行,使用redis连接Spring会话时 <context:annotation-config /> <bean

大家好, 我们有一个
Spring
项目,它使用
Spring安全性
。我们通过定义

 <b:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
而且一切都很好:)。现在,根据
doc
下一行,使用
redis
连接
Spring会话时

<context:annotation-config />
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
结果:该应用程序似乎运行良好,并且通过
redis cli进行
监控
显示
spring
正在与
redis
通信

问题 在
过滤器链中使用
springSessionRepositoryFilter
是否正常?还是我们滥用了过滤系统

谢谢

橡树

编辑 对于希望通过代码对用户进行身份验证的情况(即

Authentication authentication = authenticationManager
                .authenticate(authenticationToken);
SecurityContext securityContext = SecurityContextHolder
                .getContext();
securityContext.setAuthentication(authentication);
威尔失败了。可能是因为通过
org.springframework.security.web.FilterChainProxy
FilterChainProxy运行它还不够

web.xml
中将其作为
过滤器运行时,您认为如何

<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter>
    <filter-name>springSecurityFilterChain</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>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

springSessionRepositoryFilter
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSessionRepositoryFilter
/*
springSecurityFilterChain
/*

上述操作将强制在
springSecurityFilterChain
之前运行
springSessionRepositoryFilter
,但在本例中,
org.springframework.web.filter.DelegatingFilterProxy
被调用两次。让
springSessionRepositoryFilter
在退出
springSecurityFilterChain
filter之前作为过滤器运行的任何其他方法?

都无关紧要。从:

SessionRepositoryFilter必须放在访问HttpSession或可能提交响应的任何筛选器之前,以确保会话被正确覆盖和持久化


只要在可以提交响应或访问
HttpSession
的任何内容之前添加
springSessionRepositoryFilter
,就可以了。对于Spring安全性,您需要确保
springSessionRepositoryFilter
位于
SecurityContextPersistenceFilter
之前。这可以通过将
springSessionRepositoryFilter
包含在容器中或springsecurity的
FilterChainProxy
(即
)中来实现。

根据我的测试,
springSessionRepositoryFilter
必须首先运行。这是因为
springSessionRepositoryFilter
取代了
HttpSession
实现。下面是我使用
xml
文件的解决方案

redis-cache.xml 请注意,第一个运行的是
springSessionRepositoryFilter
。但是实际上,
org.springframework.web.filter.DelegatingFilterProxy
类正在运行,它根据bean的名称查找过滤器。所以它搜索由我们早期配置创建的bean。

另外一行关于redis cache.xml的内容也很重要。否则,我们的
spring
应用程序上下文
无法了解我们的redis配置


嘿,谢谢你的回复。上述解决方案提出了一些问题。例如,尝试执行
SecurityContext SecurityContext=SecurityContextHolder.getContext();securityContext.setAuthentication(身份验证)源代码似乎无法运行。我的想法是,即使通过
将此过滤器设置为第一个过滤器,它仍然不够,应该在它之前运行。你觉得怎么样?我知道这是个老问题。你找到解决这个问题的办法了吗?我现在面临着同样的问题,这的确是一个老问题,我想我可以在这里找到答案。你还需要吗?你好,谢谢你的回复。我们暂时从项目中删除了spring会话,因为我们无法修复此问题。如果你不需要花太多的时间去寻找答案嘿,我补充了我对这个问题的答案。希望它能帮你弄明白。谢谢你的回答。我想我们现在有一个类似的设置,但我们仍然有一些请求的问题。你认为两个DelegatingFilterProxy可能是个问题吗?
Authentication authentication = authenticationManager
                .authenticate(authenticationToken);
SecurityContext securityContext = SecurityContextHolder
                .getContext();
securityContext.setAuthentication(authentication);
<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter>
    <filter-name>springSecurityFilterChain</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>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<context:annotation-config />
<bean
    class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" />

<bean
    class="org.springframework.security.web.session.HttpSessionEventPublisher" />

<!-- end of seesion managment configuration -->


<bean id="redisConnectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <property name="port" value="${app.redis.port}" />
    <property name="hostName" value="${app.redis.hostname}" />
    <property name="password" value="${app.redis.password}" />
    <property name="usePool" value="true" />
</bean>
<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>


<filter>
    <filter-name>springSecurityFilterChain</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>

<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /WEB-INF/redis-cache.xml
    </param-value>
</context-param>

 <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>