2012-08-09 87 views
3

我发现了很多关于在heroku下强制执行HTTPS的问题,但是没有任何关于java的回复。如何在Heroku下的java雪松堆栈内执行HTTPS

下面是我找到的链接:

斯卡拉:http://www.andersen-gott.com/2012/03/using-unfiltered-and-https-on-heroku.html

Rails的:Rails - How to Redirect from http://example.com to https://www.example.com

请注意,我使用Spring MVC的3.1,所以我宁愿基于WebMvcConfigurerAdapter.addInterceptors溶液( InterceptorRegistry注册表)

回答

-1

在这里是基于弹簧MVC HTE溶液:

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 

public class ForceHerokuSsl extends HandlerInterceptorAdapter { 
    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
     String proto = request.getHeader("x-forwarded-proto"); 
     return proto == null || "https".equalsIgnoreCase(proto); 
    } 
} 
在配置

然后:

@Configuration 
@EnableWebMvc 
public class WebMvcConfig extends WebMvcConfigurerAdapter { 

    public void addInterceptors(InterceptorRegistry registry) { 
     registry.addInterceptor(new ForceHerokuSslInterceptor()); 
    } 
} 
6

这里是一个Servlet过滤器,将所有非https请求重定向到https:

package com.jamesward; 

import javax.servlet.*; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import java.io.IOException; 

public class HttpsEnforcer implements Filter { 

    private FilterConfig filterConfig; 

    public static final String X_FORWARDED_PROTO = "x-forwarded-proto"; 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
     this.filterConfig = filterConfig; 
    } 

    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 

     HttpServletRequest request = (HttpServletRequest) servletRequest; 
     HttpServletResponse response = (HttpServletResponse) servletResponse; 

     if (request.getHeader(X_FORWARDED_PROTO) != null) { 
      if (request.getHeader(X_FORWARDED_PROTO).indexOf("https") != 0) { 
       response.sendRedirect("https://" + request.getServerName() + (request.getPathInfo() == null ? "" : request.getPathInfo())); 
       return; 
      } 
     } 

     filterChain.doFilter(request, response); 
    } 

    @Override 
    public void destroy() { 
     // nothing 
    } 
} 

我做了这个作为一个Servlet过滤器,因为我无法得到一个Spring拦截器来拦截静态资产(资源)请求。

完整的源:https://github.com/jamesward/springmvc-https-enforcer

+2

request.getPa thInfo()可能会返回'null',导致像这样的字符串:'https://yourdomain.comnull',因此您可能需要在将其附加到重定向URL之前检查它。 – Erik 2015-07-24 20:22:57

+0

根据Erik的评论编辑。我一直在争取这一段时间,而且答案恰好在我的鼻子下!谢谢。 – Andy 2016-06-21 01:16:44

2

晚的答案,但替代,配置驱动的方法是对各种<sec:intercept-url>标签使用Spring Security与requires-channel="https",连同Tomcat的RemoteIpValve,它处理相同的代理头(x-forwarded-proto等等)在先前的答案中提到。该阀根据代理头改变HttpServletRequest.isSecure()的行为以反映代理报告的协议,而不是连接器实际收到的协议 - 因此,任何依赖isSecure()执行正确事情的Spring框架在卸载SSL时都会正常运行。

SSL redirects in Heroku有配置与webapp-runner和Heroku一起使用的阀门的说明。

此外,我建议使用PropertyPlaceholderConfigurer来让环境变得不可胜数。例如,在你的春季安全配置:

<sec:intercept-url pattern="/api/**" requires-channel="${REQUIRES_CHANNEL}" access="..."/> 

相关application-config.xml将包括这样的事情:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> 
    <property name="properties" ref="applicationProperties"/> 
</bean> 

<bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> 
    <property name="locations"> 
    <list> 
     <value>classpath:/application-config.properties</value> 
    </list> 
    </property> 
</bean> 

application-config.properties文件将包括REQUIRES_CHANNEL=http为默认值,然后在部署到Heroku上,你设置heroku config:set REQUIRES_CHANNEL=https重写。

0

詹姆斯的过滤器的位优化版本

import javax.servlet.*; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import java.io.IOException; 

public class HttpsFilter implements Filter { 
    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest httpReq = (HttpServletRequest) request; 
     HttpServletResponse httpResp = (HttpServletResponse) response; 
     if ("http".equalsIgnoreCase(httpReq.getHeader("x-forwarded-proto"))) { 
      StringBuffer requestURL = httpReq.getRequestURL(); 
      httpResp.sendRedirect("https" + requestURL.substring(requestURL.indexOf(":"))); 
     } else { 
      chain.doFilter(request, response); 
     } 
    } 

    @Override 
    public void destroy() { 
    } 
} 

Gist

相关问题