2017-06-27 55 views
0

我有一個使用Jetty Embedded在Java中運行的REST應用程序,運行在Heroku環境中。我想強制所有流量通過HTTPS。有關如何實現此目的的一些很好的答案,例如this onethis one。但是,所有答案都需要從文件中讀取TLS/SSL證書。我希望使用Heroku的自動證書管理(詳細信息here),以避免每年因證書過期而需要續簽證書。使用ACM意味着我無權訪問證書文件。如何通過自動證書管理強制HTTPS嵌入在Heroku上使用自動證書管理

有什麼辦法可以配置Jetty強制HTTPS而不從文件中讀取證書,或者仍然可以使用Heroku ACM?

回答

1

你可以實現doFilter這樣一個Servlet過濾器做到這一點:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
    HttpServletRequest req = (HttpServletRequest)request; 
    HttpServletResponse resp = (HttpServletResponse)response; 

    String protocol = req.getHeader("X-Forwarded-Proto"); 

    if (protocol.equals("http")) { 
     String url = "https://" + req.getServerName() + req.getContextPath() + req.getServletPath(); 
     if (req.getPathInfo() != null) { 
      url += req.getPathInfo(); 
     } 

     System.out.println("Forwarding request to: " + url); 
     resp.sendRedirect(url); 
    } else { 
     System.out.println("Not forwarding protocol: " + protocol); 
     chain.doFilter(request, response); 
    } 
} 

這裏的a complete example using Tomcat,但原理是一樣的。

+0

謝謝@codefinger。在使用Chrome時,X-Forwarded-Proto不包括在標題中,所以這對我不起作用。但是,我發現HttpServletRequest.getScheme()似乎能夠正確識別我是使用HTTP還是HTTPS,所以我會嘗試這種方法併發布結果。 –

+0

好的,調查後發現:HttpServletRequest.getScheme()不可靠(即使在Heroku上使用HTTPS時也會返回「http」),並且HttpServletRequest.isSecure()也不可靠(在Heroku上使用HTTPS時返回false )。 X-Forwarded-Proto標頭不會發送到本地運行的服務器,而是發送到在Heroku上運行的服務器。這個答案是正確的。 –

+0

我相信麻煩w/getScheme是因爲SSL終止發生在Heroku路由器(因此連接是HTTP在Servlet)。最好檢查兩個? – codefinger