繁体   English   中英

使用自定义表单登录时如何避免Spring Security重定向循环?

[英]How to avoid Spring Security redirect loop when using custom form login?

应用安全方案:

  • Spring MVC应用程序在PaaS上运行3个实例
  • 应用程序分为2个安全域。 管理瓦特位于/ 2 DispatchServlets /app/kmlservice
  • 应用程序必须在所有页面上使用https,但/kmlservice任何路径/kmlservice
  • 应用必须使用自定义登录页面才能访问/app所有路径
  • 应用程序必须使用具有LDAP身份验证的持久性记住我方案

当我们转换为https时,在尝试导航到/app/login页面或任何其他页面时,将遇到无限重定向循环。 实际上,即使未受保护的页面也会无限地重新路由到它们自己。

这是我们在尝试导航到/app/login看到的重定向日志的示例:

stdout.log: DEBUG: org.springframework.security.web.access.channel.ChannelProcessingFilter - Request: FilterInvocation: URL: /app/login; ConfigAttributes: [REQUIRES_SECURE_CHANNEL]
stdout.log: DEBUG: org.springframework.security.web.access.channel.RetryWithHttpsEntryPoint - Redirecting to: https:/some_url.com/app/login
stdout.log: DEBUG: org.springframework.security.web.DefaultRedirectStrategy - Redirecting to 'https:/some_url.com/app/login'
stdout.log: DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/app/login'; against '/kmlservice/**'
stdout.log: DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/app/login'; against '/resources/**'
stdout.log: DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/app/login'; against '/app/**'
stdout.log: DEBUG: org.springframework.security.web.FilterChainProxy - /app/login at position 1 of 12 in additional filter chain; firing Filter: 'ChannelProcessingFilter'
stdout.log: DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/app/login'; against '/app/logout'
stdout.log: DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/app/login'; against '/app/accessdenied'
stdout.log: DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/app/login'; against '/app/useful_path'
stdout.log: DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/app/login'; against '/app/help'
stdout.log: DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/app/login'; against '/app/login'
stdout.log: DEBUG: org.springframework.security.web.access.channel.ChannelProcessingFilter - Request: FilterInvocation: URL: /app/login; ConfigAttributes: [REQUIRES_SECURE_CHANNEL]
stdout.log: DEBUG: org.springframework.security.web.access.channel.RetryWithHttpsEntryPoint - Redirecting to: https:/some_url.com/app/login
stdout.log: DEBUG: org.springframework.security.web.DefaultRedirectStrategy - Redirecting to 'https:/some_url.com/app/login'

配置如下所示:

<http pattern="/kmlservice/**" use-expressions="true" auto-config="true">
    <intercept-url pattern="/**" access="isAuthenticated()" />
    <http-basic />
</http>

<http pattern="/resources/**" security="none" />

<http pattern="/app/**" use-expressions="true">
    <form-login login-page="/app/login"
        authentication-failure-url="/app/accessdenied" default-target-url="/app" />
    <intercept-url pattern="/app/logout" access="permitAll"
        requires-channel="https" />
    <intercept-url pattern="/app/accessdenied" access="permitAll"
        requires-channel="https" />
    <intercept-url pattern="/app/useful_path"
        access="hasRole('ROLE_HAS_ACCESS')" requires-channel="https" />
    <intercept-url pattern="/app/help" access="permitAll"
        requires-channel="https" />
    <intercept-url pattern="/app/login" access="IS_AUTHENTICATED_ANONYMOUSLY"
        requires-channel="https" />
    <intercept-url pattern="/app/**" access="isAuthenticated()"
        requires-channel="https" />
    <access-denied-handler error-page="/403" />
    <logout logout-success-url="/app/logout" delete-cookies="JSESSIONID" />
    <remember-me user-service-ref="userDetailsService"
        data-source-ref="dataSource" />
</http>

我试图删除<intercept-url pattern="/app/**" access="isAuthenticated()" requires-channel="https" /> ,这似乎没有什么区别

我还能提供其他有用的配置吗?
谢谢。

如果https终止于您的路由器(与PaaS配置一样常见),则您的servlet容器需要某种方法来确定传入请求是否真正安全。 Spring Security使用标准的servlet API方法isSecure来决定是否需要重定向。 我猜想在您的情况下,servlet容器无法判断对路由器的外部请求是否通过HTTPS发出。

例如,可以使用RemoteIpValve配置Tomcat,以检查特定的标头并相应地设置请求属性。 我不知道您是否对此有任何控制权,但是您可以使用一个等效的过滤器代替。 当然,这还要求您了解PaaS的设置方式,以及是否将诸如X-Forwarded-Proto类的标头X-Forwarded-Proto到您的应用程序。

由于URL / app / login被标记为IS_AUTHENTICATED_ANONYMOUSLY因此URL / app / login已得到保护,因此它处于不确定循环中。

access值更改为allowAll

<intercept-url pattern="/app/login" access="permitAll" requires-channel="https" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM