因为在这个问题中设置端口并不能解决重定向循环问题,我创建了一个基本测试应用程序(grails 2.0,最新的spring安全核心1.2.7.1),所以重定向循环问题很容易重现/有望解决:以下是步骤:
1-创建了名为test的新应用程序,并创建了一个名为simple的控制器(也在测试包中),即:
package test
class SimpleController {
def index() { redirect action: 'start' }
def start() { render "start - not secure" }
def middle() { render "middle - secure" }
def end() { render "end - not secure" }
}
2-是否安装了grails的spring-security-core以及grails s2快速启动测试用户角色
3-在Config.groovy中,添加了以下行,然后运行应用程序-https在我的开发机器上进行测试:
grails.plugins.springsecurity.secureChannel.definition = [
'/simple/middle/**': 'REQUIRES_SECURE_CHANNEL',
'/simple/end/**': 'REQUIRES_INSECURE_CHANNEL',
'/simple/**': 'ANY_CHANNEL'
]
结果:所有签出,都可以输入URL/simple/start,然后输入/simple/medle根据需要进入SSL/https模式。
4-在Config.groovy中,我配置了在Heroku上运行的端口(guestimate,找不到docs/refs):
grails.plugins.springsecurity.portMapper.httpPort = '80'
grails.plugins.springsecurity.portMapper.httpsPort = '443'
5-完成git-init、git-add的步骤后、git-commit-m"initial commit"heroku create--stack雪松,我去了heroku,并在那里新创建的应用程序中添加了PiggyBack SSL。然后我做了一个git push heroku master来部署。
结果:得到了常见的"IllegalStateException,找不到线程绑定请求",这里和这里都描述了这个问题。
6-因此,在BuildConfig.groovy中,我对插件{}部分进行了以下2项更改:
//runtime ":resources:1.1.5"
compile ":webxml:1.4.1"
结果:IllegalStateException消失了,我可以访问简单的控制器(和登录控制器)。我可以用https作为这些url的前缀,一切都很好。但是,如果我输入/简单/中间的URL,我得到重定向循环(跟踪类似于这里)。
7-出于好奇,我在步骤6中注释掉了一半的更改,即//compile:"webxml:1.4.1":
结果:得到相同的非法状态异常
8-因为我不确定heroku和云支持插件是如何融入上述基本步骤的,所以我一直等到这一步才添加它们。然后我做了grails安装插件云支持和grails安装插件heroku,并更新了BuildConfig.groovy,所以现在看起来像:
plugins {
runtime ":hibernate:$grailsVersion"
runtime ":jquery:1.7.1"
//runtime ":resources:1.1.5"
//compile ":webxml:1.4.1"
compile ':heroku:1.0'
compile ':cloud-support:1.0.8'
compile ":tomcat:$grailsVersion"
}
然后执行清理并更新git存储库并推送到heroku。
结果:相同的IllegalStateException(注意,webxml依赖项被注释掉了)。
9-然后我取消注释compile":webxml:1.4.1",并再次推出到heroku:
结果:与步骤3完全相同。也就是说,除了/简单/中间,所有URL都可以工作,包括添加https前缀。去/简单/中间URL导致重定向循环问题。
你能告诉我如何解决这个问题吗?如果有什么东西需要我尝试(即不确定的解决方案),请更新评论部分,我会回复结果。非常感谢。
------------------------------------------------------------------------------------------
使用新的spring security 1.2.7.2进行更新。
我的BuildConfig.groovy现在是:
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
runtime 'mysql:mysql-connector-java:5.1.16'
}
plugins {
runtime ":hibernate:$grailsVersion"
runtime ":jquery:1.7.1"
runtime ":resources:1.1.6"
compile ":spring-security-core:1.2.7.2"
compile ":webxml:1.4.1"
compile ':heroku:1.0'
compile ':cloud-support:1.0.8'
build ":tomcat:$grailsVersion"
}
即使使用MySql,在部署到Heroku时也出现PostGres依赖性错误。因此,我删除了Heroku上的所有应用程序,并销毁了我的git存储库,开始了一个新的部署/新的应用程序。
仍然得到这个PostGres依赖性错误(如下)。注意:之前MySql工作时收到了"找不到事务管理器-如果你的webapp需要一个,请配置一个"警告。嗯。
12-02-03T07:18:09+00:00 app[web.1]: 2012-02-03 07:18:09.810:INFO:omjr.Runner:Runner
12-02-03T07:18:09+00:00 app[web.1]: 2012-02-03 07:18:09.811:WARN:omjr.Runner:No tx manager found
12-02-03T07:18:09+00:00 app[web.1]: 2012-02-03 07:18:09.852:INFO:omjr.Runner:Deploying file:/app/target/momentum-0.1.war @ /
12-02-03T07:18:09+00:00 app[web.1]: 2012-02-03 07:18:09.869:INFO:oejs.Server:jetty-7.x.y-SNAPSHOT
12-02-03T07:18:09+00:00 app[web.1]: [o.e.j.w.WebAppContext{/,null},file:/app/target/momentum-0.1.war]
12-02-03T07:18:09+00:00 app[web.1]: 2012-02-03 07:18:09.915:INFO:oejw.WebInfConfiguration:Extract jar:file:/app/target/momentum-0.1.war!/ to /tmp/jetty-0.0.0.0-43683-momentum-0.1.war-_-any-/webapp
12-02-03T07:18:14+00:00 app[web.1]: 2012-02-03 07:18:14.500:INFO:oejpw.PlusConfiguration:No Transaction manager found - if your webapp requires one, please configure one.
12-02-03T07:18:18+00:00 app[web.1]: 2012-02-03 07:18:18.361:INFO:/:Initializing Spring root WebApplicationContext
12-02-03T07:18:24+00:00 app[web.1]:
12-02-03T07:18:24+00:00 app[web.1]: Configuring Spring Security Core ...
12-02-03T07:18:24+00:00 app[web.1]: ... finished configuring Spring Security Core
12-02-03T07:18:24+00:00 app[web.1]:
12-02-03T07:18:24+00:00 app[web.1]: 2012-02-03 07:18:24.490:WARN:oejw.WebAppContext:Failed startup of context o.e.j.w.WebAppContext{/,file:/tmp/jetty-0.0.0.0-43683-momentum-0.1.war-_-any- /webapp/},file:/a
/target/momentum-0.1.war
12-02-03T07:18:24+00:00 app[web.1]: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory';
************************************************************
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Cannot resolve reference to bean 'lobHandlerDetector' while setting bean property 'lobHandler';
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lobHandlerDetector': Invocation of init method failed;
nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'org.postgresql.Driver'
*************************************************************
12-02-03T07:18:24+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
12-02-03T07:18:24+00:00 app[web.1]: at org.codehaus.groovy.grails.commons.spring.ReloadAwareAutowireCapableBeanFactory.doCreateBean(ReloadAwareAutowireCapableBeanFactory.java:126)
12-02-03T07:18:24+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
12-02-03T07:18:24+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
12-02-03T07:18:24+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
12-02-03T07:18:24+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
12-02-03T07:18:24+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
12-02-03T07:18:24+00:00 app[web.1]: at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:707)
12-02-03T07:18:24+00:00 app[web.1]: at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:449)
12-02-03T07:18:24+00:00 app[web.1]: at org.codehaus.groovy.grails.commons.spring.DefaultRuntimeSpringConfiguration.getApplicationContext(DefaultRuntimeSpringConfiguration.java:153)
12-02-03T07:18:24+00:00 app[web.1]: at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:124)
12-02-03T07:18:24+00:00 app[web.1]: at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:165)
12-02-03T07:18:24+00:00 app[web.1]: at org.codehaus.groovy.grails.web.context.GrailsConfigUtils.configureWebApplicationContext(GrailsConfigUtils.java:121)
12-02-03T07:18:24+00:00 app[web.1]: at org.codehaus.groovy.grails.web.context.GrailsContextLoader.initWebApplicationContext(GrailsContextLoader.java:104)
12-02-03T07:18:24+00:00 app[web.1]: at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:643)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:233)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1213)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:589)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:454)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:167)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:89)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.server.Server.doStart(Server.java:261)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
12-02-03T07:18:24+00:00 app[web.1]: at org.mortbay.jetty.runner.Runner.run(Runner.java:500)
12-02-03T07:18:24+00:00 app[web.1]: at org.mortbay.jetty.runner.Runner.main(Runner.java:639)
12-02-03T07:18:24+00:00 app[web.1]: at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
如果你不知道为什么会有东西,最好不要只是随机破解:)
IllegalStateException来自web.xml中filter-mapping
元素的错误排序。spring安全核心和资源都在定位filter-mapping
元素,并且相互踩在一起,所以我们按照惯例更新了webxml插件以支持这一点,并使两个插件都依赖于该插件。由于不同依赖插件版本的插件驱逐中存在错误,因此使用依赖于同一版本webxml的spring安全核心版本和资源非常重要。
新的2.0应用程序声明对使用webxml v1.4的资源1.1.5的依赖,而spring安全核心1.2.7+使用1.4.1,因此您需要不使用资源或使用1.1.6版本。然后就没有歧义了,将使用正确的版本,web.xml的顺序也将是正确的。您还应该在BuildConfig中注册所有插件,不要使用安装插件;这将把所有的东西放在一个地方,并允许你定义排除,等等
然而,这一切都独立于SSL问题,所以最好一次只关注一个问题。我没有在Heroku上使用SSL,所以我不知道他们使用什么端口。我假设在防火墙内部,他们使用443以外的东西,然后请求在443上路由出去。但这与Grails和spring安全核心插件无关,因此了解SSL的配置方式只是一个一般的文档问题。
更新
好的,基于James发布的链接中的解决方法,我发布了一个新版本的Spring Security插件(v1.2.7.2),支持X-Forwarded-Proto。将grails.plugins.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
添加到Config.groovy
,它将使用这种方法,而不是更简单的安全/不安全检查。IllegalStateException是由于Heroku部署Grails 2.0应用程序的方式中的一个错误引起的。插件依赖关系在构建战争时没有得到解决,所以你需要明确。所以一定要添加
compile ":spring-security-core:1.2.7.2"
compile ':webxml:1.4.1'
compile ":heroku:1.0"
compile ':cloud-support:1.0.8'
到BuildConfig.groovy
,以确保webxml(一个spring安全核心依赖项)和云支持(一个heroku依赖项)得到安装和部署。