2016-04-06 102 views
1

我們有兩個節點(trunk-n1和trunk-n2)的clusterd tomcat環境,每個節點都有apache和tomcat實例,我們在以下場景中遇到問題Spring:HttpSession在Clusterd Tomcat故障轉移中爲SPRING_SECURITY_CONTEXT返回空對象

負載均衡器URL是https://trunk/PP其指向trunk-n1trunk-n2節點,當兩個節點均達到和用戶登錄到應用負載平衡器分配的一個節點(可以說N1)如果用戶是在N1,當我們把N1節點down用戶應該被無縫重定向到N2,但有時用戶會被註銷

以下是請求標頭a次春季安全調試日誌無縫重定向對於上述方案

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: '[email protected]af2e44: Authentication: org.springframew[email protected]9caf2e44: Principal: [email protected]: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]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 | [email protected] | 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 | [email protected] | 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 | [email protected] | 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 | [email protected] | 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 | [email protected] | 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 | [email protected] | 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 | [email protected] | 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 | [email protected] | 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 | [email protected] | 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 | [email protected] | kJWPdVD9IUVz | SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframew[email protected]9caf2e44: Principal: [email protected]: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]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 | [email protected] | 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 | [email protected] | 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 | [email protected] | 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: [email protected] 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.sprin[email protected]90541710: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]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: [email protected] 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 

有人可以幫助我當節點的人下來解決這個隨機用戶退出問題的用戶重定向?

回答

1

Tomcat的會話未複製,並且使用戶當節點中的一個出現故障註銷,用於hazelcast實現會話複製如下

步驟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 
    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創建hazelcast.xml:在初始化sessionRegistry豆你applicationContext.xml

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

重新啓動應用程序和會話複製工作在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