- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为 Web 应用程序的某些页面启用 HTTPS。我将 Spring MVC 和 Spring Security 用于部署在 Tomcat 上的 Web 应用程序,并使用 Nginx 作为 tomcat 的代理。
首先,无需任何 HTTPS 配置,一切正常。我生成了一个自签名 SSL 证书并将其安装在 Nginx 上。我没有对 Tomcat 进行任何更改以启用 HTTPS,因为我只希望 Nginx 处理 SSL 终止。这是我的 SSL 相关 Nginx 配置。
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>
现在,当我尝试在浏览器上访问登录页面时 - https://localhost/internal/login
,出现错误 -
This webpage has a redirect loop
Spring Security 中的日志如下所示:
12:34:55.240 [http-bio-8080-exec-33] DEBUG o.s.security.web.FilterChainProxy - /login at position 1 of 10 in additional filter chain; firing Filter: 'ChannelProcessingFilter'
12:34:55.240 [http-bio-8080-exec-33] DEBUG o.s.s.web.util.AntPathRequestMatcher - Checking match of request : '/login'; against '/login'
12:34:55.240 [http-bio-8080-exec-33] DEBUG o.s.s.w.a.c.ChannelProcessingFilter - Request: FilterInvocation: URL: /login; ConfigAttributes: [REQUIRES_SECURE_CHANNEL]
12:34:55.240 [http-bio-8080-exec-33] DEBUG o.s.s.w.a.c.RetryWithHttpsEntryPoint - Redirecting to: https://localhost/internal/login
12:34:55.241 [http-bio-8080-exec-33] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to 'https://localhost/internal/login'
我尝试使用 requires-channel 一段时间,但没有真正解决问题。任何帮助/指点都会很棒。
我尝试使用以下配置,重定向循环错误不再存在。但是,这些日志的身份验证失败 -
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 参数,这是导致问题的原因。
默认情况下,在 internalProxies 中启用了一些 IP 地址(在我的例子中,它是)。问题是身份验证间歇性地工作。我为 RemoteIpValve 启用了日志,并观察到代理 IP 是 IpV6 格式,这与 internalProxies 不匹配,因此没有为该请求启用 RemoteIpValve,因此出现了问题。我在 Mac OS X 上注释掉了 #fe80::1%lo0 localhost
行,问题就解决了。
对了,@M里面的配置。 Deinum 的回答似乎很有效。
最佳答案
您的 HTTPS 连接由 NGINX 处理。与您的应用程序的连接是 HTTP 连接。所以基本上是外在安全,内在不安全。
Spring Security 使用 isSecure()
来自 ServletRequest 的方法要确定它是否安全,默认情况下会检查协议(protocol)是否为 https。
当您使用 tomcat 时,您可以配置一个额外的阀,RemoteIpValue 3影响 isSecure()
的行为, getRemoteAddr()
方法(和其他一些方法)。
<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"
/>
将以上内容添加到 <Host >
元素(当然您可能需要删除/修改内部代理参数)。
在您的 Nginx 配置中添加 X-Forwarded-proto header 。
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;
}
或者简单地删除对安全通道的检查并假设一切正常...
链接
关于tomcat - 使用 Spring Security : This webpage has a redirect loop 启用 HTTPS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18998711/
我是一名优秀的程序员,十分优秀!