SSL redirects in Heroku

旧巷老猫 提交于 2020-01-01 07:06:12

问题


I'm having loads of trouble getting my Java web app working on Heroku.

This is what I have:

A Java web app (standard war file) using Spring Security with a security-constraint section in my web.xml that looks like this:

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>SSL URLs</web-resource-name>
            <url-pattern>/j_spring_security_check</url-pattern>
            <url-pattern>/secure/account/create</url-pattern>
            <url-pattern>/register</url-pattern>
            <url-pattern>/login/*</url-pattern>
            <url-pattern>/</url-pattern> 
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint> 

When I deploy my WAR file to Heroku (using the Heroku deploy plugin for Atlassian Bamboo) and the app starts up, I end up getting a 'too many redirects' error in my browser - it looks like it has something to do with flicking between https and http but I can't figure out what I need to do to fix it.

I just want to use the piggyback SSL for now, as the SSL add-on is quite pricey for my hobby project (at $20 a month).


回答1:


I solved a similar problem by using a combination of requires-channel in my Spring Security configuration and Tomcat's RemoteIpValve. If you are not using Spring Security, configuring RemoteIpValve should be sufficient (the following assumes you are using the excellent webapp-runner as your container) I imagine there is an equivalent for jetty-runner, but I don't know it...

The issue is that Heroku's web/routing tier handles the SSL, and proxies the request to your webapp as plain HTTP. So Tomcat doesn't know the request is secured elsewhere (SSL offloading) RemoteIpValve essentially over-rides the protocol, port and IP address that Tomcat sees (and, in turn, how request.isSecure() is evaluated) by looking at HTTP headers set by the proxying server that handled the SSL.

Create a context.xml with the following:

<Context>
  <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-forwarded-for" protocolHeader="x-forwarded-proto" portHeader="x-forwarded-port"/>
</Context>

Those three headers (x-forwarded-for, x-forwarded-proto, and x-forwarded-port) are automatically sent by Heroku's routing tier.

Next, ensure that the file gets copied somewhere in your maven target dir (I put it in the same dir as webapp-runner itself). In pom.xml:

<resources>
  <resource>
    <directory>${basedir}/src/main/resources/META-INF</directory>
    <includes>
      <include>context.xml</include>
    </includes>
    <targetPath>${project.build.directory}/dependency</targetPath>
  </resource>
</resources>

Finally, make sure webapp-runner points to the context.xml (e.g., using webapp-runner 7.0.30.1, which supports the context-xml argument). In your Procfile:

web: java $JAVA_OPTS -jar target/dependency/webapp-runner.jar --context-xml target/dependency/context.xml ...etc...

As a final note, I use of Spring Security requires-channel on <sec:intercept-url> to toggle back and forth between HTTP and HTTPS by flipping an environment variable - unset on my local dev box for easy configuration, set on Heroku (via heroku config) to selectively force SSL in different environments.

Hope this works for you...




回答2:


I was facing the exact same problem using webapp-runner and fixed it by simply using the --proxy-base-url https://example.com, as described here




回答3:


The solution provided by @bimsapi worked for me. I ran into two issues using this solution. Once I solved those it worked perfectly.

First, I had to put the context.xml file in META-INF directory directly under the root in the war file.

Second, the path to the context.xml file you provide to --context-xml attribute is the relative path from the root directory on the file system not the war file. Such as --context.xml ./tartget/myapp/META-INF/context.xml.

Before I was giving --context.xml META-INF/context.xml which was wrong.



来源:https://stackoverflow.com/questions/13397034/ssl-redirects-in-heroku

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!