[英]Spring Session with Spring Security creates two sessions
I have a Spring 4.1 web app, I use spring-security and spring session, spring session I want to use with websockets to keep the session without timeout as long as the websocket is working. 我有一个Spring 4.1 Web应用程序,我使用spring-security和spring会话,我想与websockets一起使用spring会话,以便在websocket正常工作的情况下保持会话不超时。
It all works fine but what I find is that I obviously have two sessions running, one for spring security and one for spring session. 一切正常,但是我发现我显然正在运行两个会话,一个用于Spring安全性,另一个用于Spring安全性。
This is my session.xml: 这是我的session.xml:
<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="localhost"/>
<property name="port" value="6379" />
</bean>
<bean class="org.springframework.session.data.redis.RedisOperationsSessionRepository" name="sessionRepository" >
<constructor-arg name="redisConnectionFactory" ref="jedisConnFactory" />
<!--<property name="defaultMaxInactiveInterval" value="60" />-->
</bean>
<bean class="org.springframework.session.web.http.HeaderHttpSessionStrategy" name="sessionStrategy" />
<bean name="springSessionRepositoryFilter" class="org.springframework.session.web.http.SessionRepositoryFilter">
<constructor-arg name="sessionRepository" ref="sessionRepository" />
</bean>
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" >
<property name="httpSessionStrategy" ref="sessionStrategy"/>
</bean>
And here is my security.xml: 这是我的security.xml:
<!-- Security -->
<bean id="userDetailsService" class="com.fg.ts.base.security.userdetails.CustomUserDetailsService" />
<bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder">
<constructor-arg value="${encoder.password}" />
</bean>
<sec:authentication-manager id="authenticationManager">
<sec:authentication-provider user-service-ref="userDetailsService">
<sec:password-encoder ref="passwordEncoder" />
</sec:authentication-provider>
</sec:authentication-manager>
<sec:global-method-security pre-post-annotations="enabled" secured-annotations="disabled"
jsr250-annotations="enabled" authentication-manager-ref="authenticationManager" />
<!-- Exclude the resources+error+auth pages from security filter -->
<sec:http pattern="/javax.faces.resource/**" security="none" />
<sec:http pattern="/images/**" security="none" />
<sec:http pattern="/css/**" security="none" />
<sec:http pattern="/ico/**" security="none" />
<sec:http pattern="/lib/**" security="none" />
<sec:http pattern="/js/**" security="none" />
<sec:http pattern="/auth/**" security="none" />
<sec:http pattern="/error/**" security="none" />
<sec:http pattern="/api/concordancer/search/**" security="none" />
<sec:http pattern="/concordancer/search" security="none"/>
<sec:http pattern="/assets/cdSearch.xhtml" security="none"/>
<sec:http pattern="/api/tmGroup/**" security="none"/>
<sec:http pattern="/api/reports/download/**" security="none"/>
<sec:http pattern="/api/socket/tasks/info/**" security="none"/>
<!-- Security Configuration for Faces Pages -->
<!-- Start Customization for Faces -->
<!-- ***************************** -->
<!-- Failure Login Handler -->
<bean id="authenticationFailureHandler" class="com.fg.ts.web.util.security.LoginFailureHandler">
<property name="defaultFailureUrl" value="/auth/login" />
</bean>
<!-- Faces Redirect -->
<bean id="facesRedirectStrategy" class="com.fg.ts.web.util.security.FacesRedirectStrategy">
<property name="invalidSessionUrl" value="/auth/login/sessionExpired" />
</bean>
<!-- Shared Objects -->
<bean id="securityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<!-- Session Authentication Strategy -->
<bean id="sessionFixationAuthenticationStrategy" class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />
<bean id="registerSessionStrategy" class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
</bean>
<bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<constructor-arg name="delegateStrategies">
<list>
<!-- <ref bean="concurrentSessionStrategy" /> -->
<ref bean="sessionFixationAuthenticationStrategy" />
<ref bean="registerSessionStrategy" />
</list>
</constructor-arg>
</bean>
<!-- Remember-Me Service -->
<bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<constructor-arg name="key" value="${encoder.password}" />
<constructor-arg name="userDetailsService" ref="userDetailsService" />
<property name="parameter" value="j_remember_me" />
<property name="cookieName" value="TMS_REME" />
</bean>
<!-- Filters -->
<bean id="usernamePasswordAuthenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy" />
<property name="rememberMeServices" ref="rememberMeServices" />
<property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
</bean>
<bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
<constructor-arg name="securityContextRepository" ref="securityContextRepository" />
<constructor-arg name="sessionStrategy" ref="sessionAuthenticationStrategy" />
<property name="invalidSessionStrategy" ref="facesRedirectStrategy" />
<property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
</bean>
<bean id="concurrentSessionFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<constructor-arg name="expiredUrl" value="/auth/login/expiredDueToConcurrentAccess" />
<property name="redirectStrategy" ref="facesRedirectStrategy" />
</bean>
<bean id="authEntryPoint" class="com.fg.ts.web.util.security.FacesLoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/auth/login"/>
</bean>
<!-- End Customization for Faces -->
<!-- ***************************** -->
<sec:http use-expressions="true" disable-url-rewriting="true" authentication-manager-ref="authenticationManager"
entry-point-ref="authEntryPoint"> <!--security-context-repository-ref="securityContextRepository"-->
<sec:http-basic />
<sec:custom-filter ref="usernamePasswordAuthenticationFilter" before="FORM_LOGIN_FILTER" />
<sec:custom-filter ref="sessionManagementFilter" position="SESSION_MANAGEMENT_FILTER" />
<sec:anonymous />
<sec:remember-me key="${encoder.password}" services-ref="rememberMeServices" />
<sec:form-login login-page="/auth/login" authentication-failure-handler-ref="authenticationFailureHandler" />
<sec:logout logout-url="/logout" invalidate-session="true" delete-cookies="TMS_SES,TMS_REME"
logout-success-url="/auth/login" />
<sec:session-management session-fixation-protection="none" />
<!-- General Access Control -->
<sec:intercept-url pattern="/projects/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/assets/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/setup/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/tm/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/termBase/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/quality/**" access="hasAnyRole('ROLE_ADMIN','ROLE_PM')" />
<sec:intercept-url pattern="/editor/**" access="isAuthenticated()" />
<sec:intercept-url pattern="/api/**" access="isAuthenticated()" />
<sec:intercept-url pattern="/**" access="isAuthenticated()" />
</sec:http>
How can I make spring security use the session created by spring-session ? 如何使Spring Security使用spring-session创建的会话?
I found the issue, the reason was that in the FilterChain, springSecurityFilterChain
Filter always loaded first before the springSessionRepositoryFilter
, and so the Spring Session was not yet created, so the security filter created it's own. 我发现了问题,原因是在FilterChain中, springSecurityFilterChain
过滤器始终在springSessionRepositoryFilter
之前首先加载,因此尚未创建Spring Session,因此安全过滤器创建了它自己的。
this was happening because my springSessionRepositoryFilter
was configured specifically for each servlet like this: 发生这种情况是因为我的springSessionRepositoryFilter
是为每个servlet专门配置的,如下所示:
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<servlet-name>mvc-dispatcher</servlet-name>
</filter-mapping>
but when I removed it and made it a global filter it then worked, much like this: 但是,当我删除它并将其设置为全局过滤器后,它就可以工作了,就像这样:
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.