java - Spring : HttpSession returned null object for SPRING_SECURITY_CONTEXT in Clusterd Tomcat failover

标签 java spring tomcat spring-security

我们有一个带有两个节点(trunk-n1 和 trunk-n2)的集群 tomcat 环境,每个节点都有 apache 和 tomcat 实例,我们在以下场景中遇到问题

负载均衡器 URL 是 https://trunk/PP 指向 trunk-n1trunk-n2 节点,当两个节点启动并且用户登录到应用程序负载均衡器,如果用户在 N1 上,则分配其中一个节点(比如说 N1),当我们将 N1 节点关闭时,用户应该无缝地重定向到 N2,但有时用户会被注销

下面是上述场景无缝重定向的请求头和spring security调试日志

Headers when user is on N1
    Request Headers:
        GET /PP/core/images/icons/cross.png HTTP/1.1
        Host: trunk:443
        Accept: image/webp,image/*,*/*;q=0.8
        Accept-Encoding: gzip, deflate, sdch
        Accept-Language: en-US,en;q=0.8
        Cookie: sessionIdForCognos=ADB5D9EC2AF7FC0B04795E066C429E97.trunk-n1
        Referer: https://trunk/PP/core/css/icons.css
        User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36
    Response Headers:
        HTTP/1.1 200 OK
        Accept-Ranges: bytes
        Cache-Control: max-age=315360000
        Connection: Keep-Alive
        Content-Length: 655
        Content-Type: image/png
        Date: Wed, 06 Apr 2016 17:31:19 GMT
        ETag: "28f-5234b6e15e000"
        Expires: Sat, 04 Apr 2026 17:31:19 GMT
        Keep-Alive: timeout=70, max=97
        Last-Modified: Fri, 30 Oct 2015 05:09:20 GMT
        Server: None
        Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
        X-UA-Compatible: IE=9

Headers when N1 took and redirected to N2
    Request Headers:
        GET /PP/timeout.do?ajax=true&_=1459963879470 HTTP/1.1
        Host: trunk:443
        Accept: application/json, text/javascript, */*; q=0.01
        Accept-Encoding: gzip, deflate, sdch
        Accept-Language: en-US,en;q=0.8
        Cache-Control: no-cache
        Cookie: WebDAV.activeX=false; JSESSIONID=ADB5D9EC2AF7FC0B04795E066C429E97.trunk-n1; sessionIdForCognos=ADB5D9EC2AF7FC0B04795E066C429E97.trunk-n1
        Referer: https://trunk/PP/enduser/listscreens/show.do?screenName=Lawfirm%20Invoice%20Parcels
        User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36
        X-Requested-With: XMLHttpRequest
    Response Headers:
        HTTP/1.1 200 OK
        Connection: Keep-Alive
        Content-Encoding: gzip
        Content-Length: 74
        Content-Type: text/html;charset=UTF-8
        Date: Wed, 06 Apr 2016 17:32:01 GMT
        Keep-Alive: timeout=70, max=95
        Server: None
        Set-Cookie: sessionIdForCognos=ADB5D9EC2AF7FC0B04795E066C429E97.trunk-n2; Path=/; Secure; HttpOnly
        Set-Cookie: JSESSIONID=ADB5D9EC2AF7FC0B04795E066C429E97.trunk-n2; Path=/PP; Secure; HttpOnly
        Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
        Vary: Accept-Encoding
        X-FRAME-OPTIONS: SAMEORIGIN
        X-UA-Compatible: IE=9

App log from N2
------------------------
[Apr 06 17:31:52,233] DEBUG | org.springframework.security.web.context.SecurityContextPersistenceFilter |  | kJWPdVD9IUVz | SecurityContextHolder now cleared, as request processing completed
[Apr 06 17:32:02,175] DEBUG | org.springframework.security.web.FilterChainProxy |  | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 1 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
[Apr 06 17:32:02,177] DEBUG | org.springframework.security.web.context.HttpSessionSecurityContextRepository |  | kJWPdVD9IUVz | Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@9caf2e44: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@9caf2e44: Principal: org.springframework.security.core.userdetails.User@536a6fad: Username: user1@dc.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff4c9c: RemoteIpAddress: 1.1.1.1; SessionId: CB186F4366D029B81933B16BD7E4F9A4.trunk-n1; Not granted any authorities'
[Apr 06 17:32:02,201] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 2 of 13 in additional filter chain; firing Filter: 'WelcomePageRedirectFilter'
[Apr 06 17:32:02,201] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 3 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
[Apr 06 17:32:02,201] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 4 of 13 in additional filter chain; firing Filter: 'InternalAuthenticationFilter'
[Apr 06 17:32:02,202] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
[Apr 06 17:32:02,202] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
[Apr 06 17:32:02,203] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 7 of 13 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
[Apr 06 17:32:02,203] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
[Apr 06 17:32:02,203] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
[Apr 06 17:32:02,203] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
[Apr 06 17:32:02,203] DEBUG | org.springframework.security.web.authentication.AnonymousAuthenticationFilter | user1@dc.com | kJWPdVD9IUVz | SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@9caf2e44: Principal: org.springframework.security.core.userdetails.User@536a6fad: Username: user1@dc.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff4c9c: RemoteIpAddress: 1.1.1.1; SessionId: CB186F4366D029B81933B16BD7E4F9A4.trunk-n1; Not granted any authorities'
[Apr 06 17:32:02,204] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
[Apr 06 17:32:02,204] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
[Apr 06 17:32:02,204] DEBUG | org.springframework.security.web.FilterChainProxy | user1@dc.com | kJWPdVD9IUVz | /timeout.do?ajax=true&_=1459963879470 at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'

注销用户重定向失败

Headers when user is on N2
    Request Headers:
        GET /PP/core/images/icons/pencil.png HTTP/1.1
        Host: trunk:443
        Accept: image/webp,image/*,*/*;q=0.8
        Accept-Encoding: gzip, deflate, sdch
        Accept-Language: en-US,en;q=0.8
        Cookie: sessionIdForCognos=46A37357A369A1065184EDDA3AE0ED0C.trunk-n2
        Referer: https://trunk/PP/core/css/icons.css
        User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36
    Response Headers:
        HTTP/1.1 200 OK
        Accept-Ranges: bytes
        Cache-Control: max-age=315360000
        Connection: Keep-Alive
        Content-Length: 450
        Content-Type: image/png
        Date: Wed, 06 Apr 2016 16:26:12 GMT
        ETag: "1c2-5234b6e15e000"
        Expires: Sat, 04 Apr 2026 16:26:12 GMT
        Keep-Alive: timeout=70, max=86
        Last-Modified: Fri, 30 Oct 2015 05:09:20 GMT
        Server: None
        Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
        X-UA-Compatible: IE=9

Headers when N2 is down and redirected to N1
    Request Headers:
        GET /PP/j_spring_security_logout?ajax=true&_=1459959972331 HTTP/1.1
        Host: trunk:443
        Accept: application/json, text/javascript, */*; q=0.01
        Accept-Encoding: gzip, deflate, sdch
        Accept-Language: en-US,en;q=0.8
        Cache-Control: no-cache
        Cookie: WebDAV.activeX=false; JSESSIONID=46A37357A369A1065184EDDA3AE0ED0C.trunk-n2; sessionIdForCognos=46A37357A369A1065184EDDA3AE0ED0C.trunk-n2
        Referer: https://trunk/PP/enduser/listscreens/show.do?screenName=Lawfirm%20Invoice%20Parcels
        User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36
        X-Requested-With: XMLHttpRequest
    Response Headers:
        HTTP/1.1 302 Found
        Connection: Keep-Alive
        Content-Length: 0
        Date: Wed, 06 Apr 2016 16:27:29 GMT
        Keep-Alive: timeout=70, max=83
        Location: https://trunk/PP/index.do
        Server: None
        Set-Cookie: JSESSIONID=DAD957102283938AA31F157085F9818D.trunk-n1; Path=/PP; Secure; HttpOnly
        Set-Cookie: sessionIdForCognos=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
        Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
        X-UA-Compatible: IE=9


App log
-----------------------
[Apr 06 16:27:22,305] DEBUG | org.springframework.security.web.context.SecurityContextPersistenceFilter |  | BKrUPVga5kki | SecurityContextHolder now cleared, as request processing completed
[Apr 06 16:27:29,740] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 1 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
[Apr 06 16:27:29,741] DEBUG | org.springframework.security.web.context.HttpSessionSecurityContextRepository |  |  | HttpSession returned null object for SPRING_SECURITY_CONTEXT
[Apr 06 16:27:29,741] DEBUG | org.springframework.security.web.context.HttpSessionSecurityContextRepository |  |  | No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@773b75c1. A new one will be created.
[Apr 06 16:27:29,742] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 2 of 13 in additional filter chain; firing Filter: 'WelcomePageRedirectFilter'
[Apr 06 16:27:29,742] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 3 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
[Apr 06 16:27:29,742] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 4 of 13 in additional filter chain; firing Filter: 'InternalAuthenticationFilter'
[Apr 06 16:27:29,742] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
[Apr 06 16:27:29,742] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
[Apr 06 16:27:29,742] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 7 of 13 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
[Apr 06 16:27:29,743] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
[Apr 06 16:27:29,743] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
[Apr 06 16:27:29,743] DEBUG | org.springframework.security.web.FilterChainProxy |  |  | /timeout.do?ajax=true&_=1459959972330 at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
[Apr 06 16:27:29,743] DEBUG | org.springframework.security.web.authentication.AnonymousAuthenticationFilter | anonymousUser |  | Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@90541710: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@166c8: RemoteIpAddress: 1.1.1.1; SessionId: 46A37357A369A1065184EDDA3AE0ED0C.trunk-n1; Granted Authorities: ROLE_ANONYMOUS'
[Apr 06 16:27:29,743] DEBUG | org.springframework.security.web.FilterChainProxy | anonymousUser |  | /timeout.do?ajax=true&_=1459959972330 at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
[Apr 06 16:27:29,743] DEBUG | org.springframework.security.web.FilterChainProxy | anonymousUser |  | /timeout.do?ajax=true&_=1459959972330 at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
[Apr 06 16:27:29,744] DEBUG | org.springframework.security.web.FilterChainProxy | anonymousUser |  | /timeout.do?ajax=true&_=1459959972330 at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
[Apr 06 16:27:29,744] DEBUG | org.springframework.security.web.util.matcher.AntPathRequestMatcher | anonymousUser |  | Checking match of request : '/timeout.do'; against '/admin/**'
[Apr 06 16:27:29,744] DEBUG | org.springframework.security.web.util.matcher.AntPathRequestMatcher | anonymousUser |  | Checking match of request : '/timeout.do'; against '/system/upgrade.do'
[Apr 06 16:27:29,744] DEBUG | org.springframework.security.web.util.matcher.AntPathRequestMatcher | anonymousUser |  | Checking match of request : '/timeout.do'; against '/system/upgradestatus.do'
[Apr 06 16:27:29,744] DEBUG | org.springframework.security.web.util.matcher.AntPathRequestMatcher | anonymousUser |  | Checking match of request : '/timeout.do'; against '/enduser/ajax/upgradecounts.do'
[Apr 06 16:27:29,744] DEBUG | org.springframework.security.web.util.matcher.AntPathRequestMatcher | anonymousUser |  | Checking match of request : '/timeout.do'; against '/system/**'
[Apr 06 16:27:29,744] DEBUG | org.springframework.security.web.util.matcher.AntPathRequestMatcher | anonymousUser |  | Checking match of request : '/timeout.do'; against '/enduser/**'
[Apr 06 16:27:29,744] DEBUG | org.springframework.security.web.util.matcher.AntPathRequestMatcher | anonymousUser |  | Checking match of request : '/timeout.do'; against '/changepassword.do'
[Apr 06 16:27:29,745] DEBUG | org.springframework.security.web.util.matcher.AntPathRequestMatcher | anonymousUser |  | Checking match of request : '/timeout.do'; against '/index.do'
[Apr 06 16:27:29,745] DEBUG | org.springframework.security.web.access.intercept.FilterSecurityInterceptor | anonymousUser |  | Public object - authentication not attempted
[Apr 06 16:27:29,746] INFO  | org.springframework.security.access.event.LoggerListener | anonymousUser |  | Security interception not required for public secure object: FilterInvocation: URL: /timeout.do?ajax=true&_=1459959972330
[Apr 06 16:27:29,746] DEBUG | org.springframework.security.web.FilterChainProxy | anonymousUser |  | /timeout.do?ajax=true&_=1459959972330 reached end of additional filter chain; proceeding with original chain
[Apr 06 16:27:29,751] DEBUG | org.springframework.security.web.access.ExceptionTranslationFilter | anonymousUser | uDCzcUTsm7SD | Chain processed normally
[Apr 06 16:27:29,751] DEBUG | org.springframework.security.web.context.HttpSessionSecurityContextRepository |  | uDCzcUTsm7SD | SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
[Apr 06 16:27:29,751] DEBUG | org.springframework.security.web.context.SecurityContextPersistenceFilter |  | uDCzcUTsm7SD | SecurityContextHolder now cleared, as request processing completed
[Apr 06 16:27:29,767] DEBUG | org.springframework.security.web.FilterChainProxy |  | BKrUPVga5kki | /j_spring_security_logout?ajax=true&_=1459959972331 at position 1 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
[Apr 06 16:27:29,768] DEBUG | org.springframework.security.web.context.HttpSessionSecurityContextRepository |  | BKrUPVga5kki | HttpSession returned null object for SPRING_SECURITY_CONTEXT
[Apr 06 16:27:29,768] DEBUG | org.springframework.security.web.context.HttpSessionSecurityContextRepository |  | BKrUPVga5kki | No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@773b75c1. A new one will be created.
[Apr 06 16:27:29,768] DEBUG | org.springframework.security.web.FilterChainProxy |  | BKrUPVga5kki | /j_spring_security_logout?ajax=true&_=1459959972331 at position 2 of 13 in additional filter chain; firing Filter: 'WelcomePageRedirectFilter'
[Apr 06 16:27:29,768] DEBUG | org.springframework.security.web.FilterChainProxy |  | BKrUPVga5kki | /j_spring_security_logout?ajax=true&_=1459959972331 at position 3 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
[Apr 06 16:27:29,768] DEBUG | org.springframework.security.web.FilterChainProxy |  | BKrUPVga5kki | /j_spring_security_logout?ajax=true&_=1459959972331 at position 4 of 13 in additional filter chain; firing Filter: 'InternalAuthenticationFilter'
[Apr 06 16:27:29,769] DEBUG | org.springframework.security.web.FilterChainProxy |  | BKrUPVga5kki | /j_spring_security_logout?ajax=true&_=1459959972331 at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
[Apr 06 16:27:29,769] DEBUG | org.springframework.security.web.authentication.logout.LogoutFilter |  | BKrUPVga5kki | Logging out user 'null' and transferring to logout destination
[Apr 06 16:27:29,769] DEBUG | org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler |  | BKrUPVga5kki | Invalidating session: 46A37357A369A1065184EDDA3AE0ED0C.trunk-n1
[Apr 06 16:27:29,778] DEBUG | org.springframework.security.web.DefaultRedirectStrategy |  | BKrUPVga5kki | Redirecting to '/PP/index.do'
[Apr 06 16:27:29,778] DEBUG | org.springframework.security.web.context.HttpSessionSecurityContextRepository |  | BKrUPVga5kki | SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
[Apr 06 16:27:29,779] DEBUG | org.springframework.security.web.context.SecurityContextPersistenceFilter |  | BKrUPVga5kki | SecurityContextHolder now cleared, as request processing completed

有人可以帮我解决当其中一个节点宕机时这个随机用户注销问题吗?

最佳答案

Tomcat session 没有被复制,导致用户在其中一个节点宕机时注销,配置hazelcast 来实现session 复制,如下所示

第 1 步:将以下依赖项添加到 pom.xml

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast</artifactId>
        <version>3.6.2</version>
    </dependency>
    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast-wm</artifactId>
        <version>3.6.2</version>
    </dependency>

第 2 步:在 web.xml 中的现有过滤器之上添加以下代码段,以便请求首先转到 hazelcast

<filter>
    <filter-name>hazelcast-filter</filter-name>
    <filter-class>com.hazelcast.web.spring.SpringAwareWebFilter</filter-class>
    <!--
        Name of the distributed map storing
        your web session objects
    -->
    <init-param>
        <param-name>map-name</param-name>
        <param-value>my-sessions</param-value>
    </init-param>
    <init-param>
        <param-name>config-location</param-name>
        <param-value>/WEB-INF/hazelcast.xml</param-value>
    </init-param>
    <init-param>
        <param-name>sticky-session</param-name>
        <param-value>true</param-value>
    </init-param>
    <!-- Are you debugging? Default is false.-->
    <init-param>
        <param-name>debug</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>hazelcast-filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>
<listener>
    <listener-class>com.hazelcast.web.SessionListener</listener-class>
</listener>

第 3 步:创建 hazelcast.xml 如下

<hazelcast
    xsi:schemaLocation="http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.6.xsd"
    xmlns="http://www.hazelcast.com/schema/config"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</hazelcast>

第 4 步:在您的 applicationContext.xml

中初始化 sessionRegistry bean
<bean id="sessionRegistry" 
    class="org.springframework.security.core.session.SessionRegistryImpl" /> 

重启你的应用程序, session 复制在 tomcat 故障转移上工作

文档引用:
http://hazelcast.org/use-cases/clustering/ http://docs.hazelcast.org/docs/3.5/manual/html/websessionreplication.html http://docs.hazelcast.org/docs/3.6/manual/html-single/index.html#preface

配置引用:
https://github.com/hazelcast/hazelcast-code-samples/tree/master/hazelcast-integration/spring-security

关于java - Spring : HttpSession returned null object for SPRING_SECURITY_CONTEXT in Clusterd Tomcat failover,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36463054/

相关文章:

java - Spring Boot 5 WebClient 在检查 HTTP 响应 header 之前先验证 HTTPStatus

java - Spring security Oauth 2 在/oauth/token上重定向行为

Java 7 update 11 在 IE8 上使用 Apache Tomcat 6.0.36 破坏了 webb 应用程序

java - 当我们将类名定义为 String 时会发生什么?

java - 无法将 HashSet 解析为 JSONObject 字符串

java - 我如何在 RxJava 中显式地发出 Flowable 完成的信号?

rest - 如何将swagger-ui与部署在运行在eclipse上的tomcat中的服务一起使用

java - 在 Java 中命令线程的执行

javascript - 无法在新选项卡中打开 pdf 文件

java.lang.UnsatisfiedLinkError : Native Library XXX. 所以已经加载到另一个类加载器中