【问题标题】:Load Balancing using apache http and Spring security使用 apache http 和 Spring 安全性进行负载平衡
【发布时间】:2016-12-28 14:23:04
【问题描述】:

我正在使用 apache http、mod-jk 和两个 tomcat 服务器来平衡我的应用程序的负载平衡,该应用程序使用 spring 安全性。启动应用程序时,出现以下错误

 Error code: ERR_TOO_MANY_REDIRECTS 

以前有人见过这个问题吗?是否有任何配置可以让负载均衡器工作。 如果我从我的应用程序中删除 spring 安全性,负载均衡器可以正常工作。

Web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- The definition of the Root Spring Container shared by all Servlets 
    and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring-security.xml,/WEB-INF/spring/root-context.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
    <servlet-name>oAuth</servlet-name>
    <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>oAuth</servlet-name>
    <url-pattern>/oAuth</url-pattern>
</servlet-mapping>
<session-config>
    <session-timeout>60</session-timeout>
</session-config>
<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
    <welcome-file>/index.html</welcome-file>
</welcome-file-list>

Spring-Security.xml

  <?xml version="1.0" encoding="UTF-8"?>
   <beans:beans xmlns="http://www.springframework.org/schema/security"
   xmlns:beans="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!--HTTP Interceptors for authentication -->
<http pattern="/templates/**" security="none"></http>
<http pattern="/css/**" security="none"></http>
<http pattern="/js/**" security="none"></http>
<http pattern="/lib/**" security="none"></http>
<http pattern="/lib/css/**" security="none"></http>
<http pattern="/lib/js/**" security="none"></http>
<http pattern="/lib/fonts/**" security="none"></http>
<http pattern="/img/**" security="none"></http>
<http pattern="/rest/**" security="none"></http>
<http pattern="/oAuth" security="none"></http>
<http entry-point-ref="entryPoint"
    auto-config="true" use-expressions="true">
    <anonymous enabled="false"></anonymous>
    <custom-filter ref="oAuthFilter" after="SECURITY_CONTEXT_FILTER"></custom-filter>
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')"></intercept-url>
</http>

<authentication-manager alias="upmAuthenticationManager"></authentication-manager>
<beans:bean id="entryPoint" class="auth.EntryPoint">
    <beans:constructor-arg value="/index.html"></beans:constructor-arg>
</beans:bean>

<beans:bean id="oAuthEnd" name="auth.oAuthEnd"
    class="oAuth.OAuthServlet">
    <beans:property name="oAuthFilter" ref="oAuthFilter"></beans:property>
</beans:bean>
<beans:bean id="oAuthFilter" class="auth.filter">
    <beans:property name="id"
        value=""></beans:property>
    <beans:property name="secret"
        value=""></beans:property>
    <beans:property name="url"
        value=""></beans:property>
</beans:bean>

mod-jk 配置

worker.server1.port=8009
worker.server1.host=localhost
worker.server1.type=ajp13

worker.server2.port=9009
worker.server2.host=localhost
worker.server2.type=ajp13

worker.server1.lbfactor=1
worker.server2.lbfactor=1

worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=server1,server2
worker.status.type=status

<VirtualHost *:80>
    JkMount /status status
    JkMount /* loadbalancer
    ServerAdmin webmaster@localhost
    DocumentRoot /data/www/
    <location />
            Require all granted
    </location>

    ErrorLog ${APACHE_LOG_DIR}/www_error.log
    CustomLog ${APACHE_LOG_DIR}/www_access.log combined
 </VirtualHost>

【问题讨论】:

    标签: spring apache tomcat spring-security


    【解决方案1】:

    Apache httpd 和 mod_jk 恐怕不会造成麻烦。

    没有看到你的配置很难说,但我敢打赌,你的 Spring 安全配置已经配置了一个安全的登录页面,所以它总是重定向到你无法访问的页面。

    您能发布您的 web.xml 和安全配置吗?也许 mod_jk 映射到 Tomcat 也会有所帮助。

    编辑: 我认为将 sticky_session 设置为 true 可以解决问题。尝试将此添加到您的 mod_jk 配置中:

    worker.loadbalancer.sticky_session=1
    

    EDIT2:将 jvmRoute 属性设置为 worker.loadbalancer.members 中配置的值解决了问题。

    发生的情况是 mod_jk 使用会话 cookie 中作为后缀的值来检查它与负载均衡器成员名称的对比,以找出会话打开的客户端。由于 jvmRoute 没有值,所以 JSESSIONID 没有后缀,所以 mod_jk 不知道要向哪个 worker 发送请求,所以 balancer 根据 lbfactor 选择一个 worker。

    由于这个值对两个工作人员都配置了相同的值,每个传入的请求都被重定向到上一个请求中没有选择的工作人员,所以没有机会到达登录表单,也没有执行登录(或任何登录机制正在使用中)。

    【讨论】:

    • 我发布了 web.xml 和安全配置。应用程序在一台 tomcat 服务器上运行良好
    • 谢谢。我将sticky_session 添加到配置文件中。我仍然看到同样的问题
    • 您的 server.xml 的引擎部分是否配置了与您为每个平衡器成员提供的名称相匹配的 jvmRoute? server1 必须配置 和 server2 你重启了 Apache设置会话粘性后的httpd?
    • 非常感谢。 jvmRoute 是问题,添加后它起作用了。我有一个问题。没有 spring 安全负载平衡运行良好。这怎么可能?
    • 因为 spring security 会重定向到配置的身份验证入口点。所以,它来了一个请求,mod_jk 选择了 server1,spring security 发现它没有一个有效的会话,所以它发送一个 301/302 到达入口点,浏览器执行重定向,然后 mod_jk 选择另一个服务器,它不知道传入的 JSESSIONID 并再次开始重定向循环......永远这样......
    猜你喜欢
    • 2018-03-12
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 2018-12-20
    • 2013-03-24
    • 2011-04-15
    相关资源
    最近更新 更多