负载均衡(AWS Beanstalk)环境中的Spring安全性失败?

时间:2014-08-06 13:49:38

标签: java spring amazon-web-services spring-security elastic-beanstalk

我正在研究一种在现有环境中运行良好的现有代码。该应用程序有一个登录表单,可以在用户登录后将其带到登录页面。

我的问题:当我将应用程序移动到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日志有1个额外行,第2行
  • AWS日志显示最后一行第5行从exec-7到exec-9的线程更改(因此它丢失了原始请求重定向并将其替换回/login.html而不是/secure/landing.html )

为了解决AWS中正在发生的问题,将beanstalk重新配置为仅使用1个实例似乎可以隐藏问题。

知道在多节点环境中失败的配置中缺少什么?

2 个答案:

答案 0 :(得分:4)

使用负载均衡器时,必须记住,每个请求都可以在不同的实例上结束。在这种情况下,服务器1上存储的任何信息都不可用于服务器2.在用户身份验证的情况下,有几种方法可以解决此问题:

  • 使用第三方维护身份验证信息。
  • 使用粘性会话 - 将负载均衡器配置为始终转发到一台服务器 在http会话期间

答案 1 :(得分:0)

根据Spring Security documentation,您需要确保使用非ThreadLocal模式设置SecurityContextHolder bean。默认情况下,我认为它是使用MODE_THREADLOCAL设置的,它似乎不会在弹性beanstalk设置的线程系统中持续存在。

strategyName = SecurityContextHolder.MODE_INHERITABLETHREADLOCALMODE_GLOBAL注入SecurityContextHolder bean并告诉我是否有效。