Grails Spring Security 使用 https 重定向到登录页面
Posted
技术标签:
【中文标题】Grails Spring Security 使用 https 重定向到登录页面【英文标题】:Grails Spring Security redirect to login page using https 【发布时间】:2014-01-01 14:03:30 【问题描述】:我有一个使用 Spring Security Core 的 Grails 应用程序,在负载均衡器后面的 AWS 机器上运行。
负载均衡器解密 ssl 连接并转发到我们实例的端口 8080,添加适当的 X-Forwarded-Proto 标头。
我希望对安全页面的任何直接访问以使用 https 重定向到登录页面。
例如,请求 https://myapp.com/private/page 应该重定向到 https://myapp.com/login/auth
我把它放在我的 config.groovy 中:
grails.plugin.springsecurity.secureChannel.definition = [
'/login/**': 'REQUIRES_SECURE_CHANNEL'
]
但这会导致重定向循环(HTTP 代码 302)到 http 登录页面 (http://myapp.com/login/auth)
然后我尝试了:
grails.plugin.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugin.springsecurity.auth.forceHttps = true
但这会导致重定向(HTTP 代码 302)到 http 登录页面 (http://myapp.com/login/auth)
-
问题仅存在于生产设置(战争部署到负载平衡器后面的 Tomcat)。
如果我在本地开发机器上测试相同的 config.groovy,重定向到 https://myapp.com/login/auth 就可以了。
我尝试为 spring 安全性指定不同的 httpsPort,它再次在我的本地开发机器上工作,但在不断重定向到 http 的已部署应用程序中被完全忽略
没有运气潜伏在类似的帖子,知道吗?
【问题讨论】:
【参考方案1】:我还在 AWS 上使用带有 https 和负载均衡器的 Spring Security Core 2.0-RC4 托管我的 Grails 应用程序,感谢 spock99(上图)和 AWS 的 Ravi L,我得到了它的工作。
我在 config.groovy 中做了以下操作:
// Required because user auth uses absolute redirects
grails.serverURL = "http://example.com"
grails.plugin.springsecurity.secureChannel.definition = [
'/assets/**': 'ANY_CHANNEL',// make js, css, images available to logged out pages
'/**': 'REQUIRES_SECURE_CHANNEL',
]
// overriding values in DefaultSecurityConfig.groovy from the SpringSecurityCore 2.0-RC4
grails.plugin.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugin.springsecurity.portMapper.httpPort = 80
grails.plugin.springsecurity.portMapper.httpsPort = 443
注意:Spring Security Core 2.0-RC4 中不需要以下内容 - 它们已经在 DefaultSecurityConfig.groovy 中
secureHeaderName = 'X-Forwarded-Proto'
secureHeaderValue = 'http'
insecureHeaderName = 'X-Forwarded-Proto'
insecureHeaderValue = 'https'
我得到了错误的“不健康”读数,因为点击“/”会返回一个 302 重定向到 /login/auth,所以我向 HomeController(我映射到“/health”)添加了一个 health() 方法以供 AWS 命中:
class HomeController
@Secured('IS_AUTHENTICATED_FULLY')
def index()
@Secured('permitAll')
def health() render ''
对我而言,关键是在负载均衡器上运行多个实例时会话 cookie 没有得到正确处理(直到将最小实例设置为 2,我才发现这一点),所以为了让用户能够登录并保持登录状态,我在 AWS 上做了以下操作:
1. At Services / Elastic Beanstalk / Configuration / Load Balancing
a. set Application health check URL: /health
b. left Session Stickiness: unchecked
2. At Services / EC2 / Load Balancers / Description / Port Configuration:
For both port 80 (HTTP) and 443 (HTTPS)
1. Edit and select 'Enable Application Generated Cookie Stickiness'
2. Cookie Name: JSESSIONID
【讨论】:
【参考方案2】:我刚刚经历了同样的场景。卡在https上,然后是重定向,现在一切都很好。使用这些 Config.groovy 设置:
grails.plugin.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugin.springsecurity.portMapper.httpPort = 80
grails.plugin.springsecurity.portMapper.httpsPort = 443
grails.plugin.springsecurity.secureChannel.secureHeaderName = 'X-Forwarded-Proto'
grails.plugin.springsecurity.secureChannel.secureHeaderValue = 'http'
grails.plugin.springsecurity.secureChannel.insecureHeaderName = 'X-Forwarded-Proto'
grails.plugin.springsecurity.secureChannel.insecureHeaderValue = 'https'
注意那些不使用springsecurity 2.0的人,它是'plugins'而不是'plugin'没有's'。
我的 beanstalk 负载平衡器设置如下所示(我安装了 SSL 证书,我没有显示):
在 EC2 负载均衡器设置中,确保您的侦听器设置正确:
最后在 EC2 安全组中确保 EB 接受来自 ELB 的端口 80 和 443 上的请求:
请注意,在我的任何设置中,我都没有引用端口 8080 或 8443,即使这是我在本地主机上用于测试的端口。阅读本文的人可能会考虑尝试使用这些端口来解决问题。我的设置不需要。
【讨论】:
非常感谢您的帮助,但没有运气!我复制了相同的设置,也将内部端口移动到 80,但它总是重定向到 http...你在 grails.plugin.springsecurity.secureChannel.definition 中有什么吗?关于如何至少调试它的任何想法? 我没有为secureChannel.definition 设置值。您是否为生产环境设置了 grails.serverURL?那是破坏我的应用程序的另一件事,但我认为这与设置云端有关。我没有用日志调试它。我会在配置文件中进行更改并上传新的战争,然后使用浏览器逐步完成每个场景以查看发生了什么问题。然后我会做出改变,然后再试一次。 你用的是什么版本的spring security? 对于生产我有:grails.serverURL = "my.app.com"。我正在使用“:spring-security-core:2.0-RC2” 我的服务器网址是 http://www.mycompany.com。我不知道http是否会有所作为。我也在使用RC2。您没有使用 VPC 是吗?我在使用 VPC 时遇到了很多麻烦,最终将所有 VPC 从 AWS 中剥离出来。在与 AWS 支持协商了近一个小时后,我的设置没有必要。【参考方案3】:我在类似的环境中遇到了类似的问题,其中前端在 https 上,而防火墙 grails 服务器在 http 上。 当会话超时时,ajax 和 angular $http 用于获取重定向消息到http://myclient.com/myWar/login/auth。此重定向请求用于导致浏览器中的访问被拒绝,因为原始 url 是 https 并且混合内容被禁用。 我曾经得到 SCRIPT7002: XMLHttpRequest: Network Error 0x80700013, 由于错误 80700013 无法完成操作。” 此错误仅发生在生产环境中,而不发生在测试环境中。
修复很简单,只需将以下内容添加到配置文件中即可。 grails.serverURL = "https://mywebsitespublicaddress.com/myWar"
【讨论】:
以上是关于Grails Spring Security 使用 https 重定向到登录页面的主要内容,如果未能解决你的问题,请参考以下文章
Grails - grails-spring-security-rest - 无法从 application.yml 加载 jwt 机密
使用 Spring Security Grails 插件编码密码
Grails + spring-security-core:用户登录后如何分配角色?