应用安全场景:
- Spring MVC应用程序在PaaS上运行3个示例
- 应用程序分为2个安全域。使用位于
/app
和/kmlservice
的2个DispatchServlet进行管理 - 应用程序必须在所有页面上使用https,除了
/kmlservice
中的任何路径 - 应用程序必须使用自定义登录页面访问
/app
中的所有路径 - 应用程序必须使用具有LDAP身份验证的永久Remember-Me方案
当我们转换到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" />
,这似乎没有什么区别
还有其他有用的配置我可以提供吗?
谢谢。
3条答案
按热度按时间nnt7mjpx1#
如果https终止于您的路由器,这是PaaS配置的常见情况,那么您的servlet容器需要某种方法来确定传入的请求是否实际安全。Spring Security使用标准的servlet API方法isSecure来决定是否需要重定向。我猜在您的情况下,servlet容器无法判断对路由器的外部请求是否通过HTTPS发出。
例如,Tomcat可以配置RemoteIpValve来检查特定的头部并相应地设置请求属性。我不知道你是否可以控制这一点,但你可以使用equivalent filter。当然,这也需要你知道你的PaaS是如何设置的,以及它是否会将像
X-Forwarded-Proto
这样的头部转发到你的应用。xzlaal3s2#
这是一个不确定的循环,因为URL /app/login 是安全的,因为它被标记为
IS_AUTHENTICATED_ANONYMOUSLY
。将
access
值更改为 permitAllru9i0ody3#
看看这个https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#_multiple_httpsecurity_instances
基本上,你可以使用第一个filterChainApi和“.securityMatcher”作为你的api,使用第二个filterChainMvc和.formLogin作为你的MVC。