Tomcat 使用Spring Security启用HTTPS:此网页具有重定向循环
我正在尝试为web应用程序上的某些页面启用HTTPS。我将SpringMVC和SpringSecurity用于部署在Tomcat上的web应用程序,其中Nginx作为Tomcat的代理 首先,没有任何HTTPS配置,一切正常。我生成了一个自签名SSL证书,并将其安装在Nginx上。我没有对Tomcat进行任何更改以启用HTTPS,因为我只希望Nginx处理SSL终止。下面是我针对SSL的相关Nginx配置Tomcat 使用Spring Security启用HTTPS:此网页具有重定向循环,tomcat,ssl,nginx,spring-security,Tomcat,Ssl,Nginx,Spring Security,我正在尝试为web应用程序上的某些页面启用HTTPS。我将SpringMVC和SpringSecurity用于部署在Tomcat上的web应用程序,其中Nginx作为Tomcat的代理 首先,没有任何HTTPS配置,一切正常。我生成了一个自签名SSL证书,并将其安装在Nginx上。我没有对Tomcat进行任何更改以启用HTTPS,因为我只希望Nginx处理SSL终止。下面是我针对SSL的相关Nginx配置 listen 443; server_name 127
listen 443;
server_name 127.0.0.1;
root /usr/local/server/web/webapps/ROOT;
ssl on;
ssl_certificate /usr/local/etc/nginx/ssl/server.crt;
ssl_certificate_key /usr/local/etc/nginx/ssl/server.key;
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
我的SSL的Spring安全配置如下所示:
<http pattern="/static/**" security="none" />
<http pattern="/favicon*" security="none" />
<http use-expressions="true">
<intercept-url pattern="/login" access="permitAll" requires-channel="https" />
<intercept-url pattern="/loginprocess" method="POST" requires-channel="https" />
<intercept-url pattern="/logout" access="isAuthenticated()"/>
<intercept-url pattern="/**" access="isAuthenticated()" requires-channel="https" />
<form-login username-parameter="username"
password-parameter="password" login-page="/login"
login-processing-url="/loginprocess" default-target-url="/hiring"
authentication-failure-url="/login?error" always-use-default-target="true" />
<logout logout-url="/logout" logout-success-url="/login?logout" />
</http>
我试着玩了一段时间,但没有真正的工作。任何帮助/指点都很好
更新
我尝试使用下面的配置,重定向循环错误不再存在。但是,这些日志的身份验证失败-
03:29:28.603 [http-bio-8080-exec-19] DEBUG o.s.s.w.a.c.ChannelProcessingFilter - Request: FilterInvocation: URL: /loginprocess; ConfigAttributes: [REQUIRES_SECURE_CHANNEL]
03:29:28.603 [http-bio-8080-exec-19] DEBUG o.s.s.w.a.c.RetryWithHttpsEntryPoint - Redirecting to: https://localhost/internal/loginprocess
03:29:28.603 [http-bio-8080-exec-19] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to 'https://localhost/internal/loginprocess'
03:29:28.609 [http-bio-8080-exec-11] DEBUG o.s.s.web.util.AntPathRequestMatcher - Request 'GET /loginprocess' doesn't match 'POST /loginprocess
03:29:28.609 [http-bio-8080-exec-11] DEBUG o.s.s.web.util.AntPathRequestMatcher - Request '/loginprocess' matched by universal pattern '/**'
03:29:28.614 [http-bio-8080-exec-20] DEBUG o.s.security.web.FilterChainProxy - /loginprocess at position 4 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
03:29:28.614 [http-bio-8080-exec-20] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Request is to process authentication
03:29:28.615 [http-bio-8080-exec-20] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Authentication method not supported: GET
我想知道,当Spring Security向浏览器发送重定向并返回GET请求时,这是否也是同样的问题。但是,如果登录登录页面是HTTPS,Spring因为RemoteIPValve而认为它是安全的,那么为什么上面又出现了问题呢
解决方案
我没有在RemoteIpValve中添加internalProxies参数,这是导致问题的原因。默认情况下,在InternalProxy中启用了一些IP地址(在我的例子中,它是)。问题是,身份验证间歇性地工作。我为RemoteIpValve启用了日志,并观察到代理IP采用IpV6格式,这与internalProxies不匹配,因此RemoteIpValve没有为该请求启用,因此出现了问题。我在Mac OS X上注释掉了#fe80::1%lo0 localhost
行,问题就解决了
顺便说一句,@M.Deinum的答案中的配置似乎运行良好 您的HTTPS连接由NGINX处理。与应用程序的连接是HTTP连接。因此,基本上是外部安全,内部不安全 Spring Security使用中的
isSecure()
方法来确定它是否是安全的,默认情况下,这将检查协议是否为https
在使用tomcat时,您可以配置一个额外的阀,即RemoteIpValue,以影响isSecure()
、getRemoteAddr()
方法(以及其他一些方法)的行为
或者干脆取消对安全通道的检查,并假设一切正常
链接
谢谢这似乎是一些工作。在tomcat上启用HTTPS是一个更简单的配置选项吗?在安全性方面是否也更好?我的意思是,通过配置SSL连接器来接受tomcat中的安全连接,我当前的配置是否能正常工作?您可以添加
RemoteIpValve
或将SSL添加到tomcat中的连接器中。两者都需要配置,RemoteIpValve似乎最简单。另一个解决方案是创建一个servlet过滤器,它包装请求并覆盖isSecure
方法(并检查X-Forwarded-for头或其他安全的东西)。
03:29:28.603 [http-bio-8080-exec-19] DEBUG o.s.s.w.a.c.ChannelProcessingFilter - Request: FilterInvocation: URL: /loginprocess; ConfigAttributes: [REQUIRES_SECURE_CHANNEL]
03:29:28.603 [http-bio-8080-exec-19] DEBUG o.s.s.w.a.c.RetryWithHttpsEntryPoint - Redirecting to: https://localhost/internal/loginprocess
03:29:28.603 [http-bio-8080-exec-19] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to 'https://localhost/internal/loginprocess'
03:29:28.609 [http-bio-8080-exec-11] DEBUG o.s.s.web.util.AntPathRequestMatcher - Request 'GET /loginprocess' doesn't match 'POST /loginprocess
03:29:28.609 [http-bio-8080-exec-11] DEBUG o.s.s.web.util.AntPathRequestMatcher - Request '/loginprocess' matched by universal pattern '/**'
03:29:28.614 [http-bio-8080-exec-20] DEBUG o.s.security.web.FilterChainProxy - /loginprocess at position 4 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
03:29:28.614 [http-bio-8080-exec-20] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Request is to process authentication
03:29:28.615 [http-bio-8080-exec-20] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Authentication method not supported: GET
<Valve
className="org.apache.catalina.valves.RemoteIpValve"
internalProxies="192\.168\.0\.10|192\.168\.0\.11"
remoteIpHeader="x-forwarded-for"
proxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto"
/>
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Front-End-Https on;
proxy_set_header Host $http_host;
}