我正在研究一种在现有环境中运行良好的现有代码。该应用程序有一个登录表单,可以在用户登录后将其带到登录页面。
我的问题:当我将应用程序移动到AWS Beanstalk(带有2个实例)时,成功登录会将用户带回登录页面
该应用程序是基于Spring的(MVC,安全性),具有以下安全配置:
<security:http use-expressions="true">
<security:intercept-url pattern="/" access="permitAll" />
<security:intercept-url pattern="/index.html" access="permitAll" />
<security:intercept-url pattern="/login.html" access="permitAll" />
... bunch of other pages ....
<security:intercept-url pattern="/secure/**" access="isAuthenticated()" />
<security:form-login login-page="/login.html"
default-target-url="/secure/landing.html"
authentication-failure-url="/login.html?login_error=1" />
<security:logout logout-url="/logout.html"
logout-success-url="/login.html" />
</security:http>
应用程序在单节点环境中正常工作,例如用户登录时的日志跟踪示例:
1: [http-bio-8080-exec-1 DEBUG DefaultRedirectStrategy - sendRedirect - 重定向到'/myapp/secure/landing.html'
2: [http-bio-8080-exec-1] DEBUG HttpSessionSecurityContextRepository - saveContext - 存储到HttpSession的SecurityContext:'org.springframework.security.core.context.SecurityContextImpl@86073c69:/ *一些细节* /授权机构:ROLE_USER'
3: [http-bio-8080-exec-1] DEBUG SecurityContextPersistenceFilter - doFilter - SecurityContextHolder现已清除,请求处理已完成
4: [http-bio-8080-exec-1] DEBUG AntPathRequestMatcher - 匹配 - 检查请求匹配:'/ security / landing.html';反对'/ resources / **'
当这个应用程序(我们使用完全相同的war文件)进入AWS Beanstalk环境,配置了2个实例时,就会发生这种情况:
1: [http-bio-8080-exec-7] DEBUG DefaultRedirectStrategy - sendRedirect - 重定向到'/secure/landing.html'
2: [http-bio-8080-exec-7] DEBUG HttpSessionSecurityContextRepository - createNewSessionIfAllowed - 作为SecurityContext创建的HttpSession是非默认的
3: [http-bio-8080-exec-7] DEBUG HttpSessionSecurityContextRepository - saveContext - 存储到HttpSession的SecurityContext: 'org.springframework.security.core.context.SecurityContextImpl@a3421210:/ *一些细节* /授权机构:ROLE_USER'
4: [http-bio-8080-exec-7] DEBUG SecurityContextPersistenceFilter - doFilter - SecurityContextHolder现已清除,请求处理已完成
5: [http-bio-8080-exec-9] DEBUG AntPathRequestMatcher - 匹配 - 检查请求匹配:'/ login.html';反对'/ resources / **'
逐行比较:
为了解决AWS中正在发生的问题,将beanstalk重新配置为仅使用1个实例似乎可以隐藏问题。
知道在多节点环境中失败的配置中缺少什么?
答案 0 :(得分:4)
使用负载均衡器时,必须记住,每个请求都可以在不同的实例上结束。在这种情况下,服务器1上存储的任何信息都不可用于服务器2.在用户身份验证的情况下,有几种方法可以解决此问题:
答案 1 :(得分:0)
根据Spring Security documentation,您需要确保使用非ThreadLocal模式设置SecurityContextHolder bean。默认情况下,我认为它是使用MODE_THREADLOCAL
设置的,它似乎不会在弹性beanstalk设置的线程系统中持续存在。
将strategyName = SecurityContextHolder.MODE_INHERITABLETHREADLOCAL
或MODE_GLOBAL
注入SecurityContextHolder bean并告诉我是否有效。