How to redirect http request to https on java application installed on Amazon ElasticBeanstalk

自古美人都是妖i 提交于 2019-12-11 03:29:23

问题


I am using Amazon ElasticBeanstalk for my Java EE web application deployment. I want my application should be https only so i have configured SSL certificate on ElasticLoadbalancer. also i have configured web.xml file as

<security-constraint>
    <web-resource-collection>
        <web-resource-name>HTTPSOnly</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>      
    <user-data-constraint>      
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
  </security-constraint>

But the problem is when i hit http://www.myweb.com then it redirect to http://www.myweb.com:8443 so i want to remove the port from url Amazon EBS & Load balancer working explained as below


回答1:


I also went down the path of adding the securityConstraint in my web.xml. With the stock server.xml that EB deploys with your application however you get a redirct to port 8443. You can edit this file by hand but it gets blown away on your next deployment. Research suggested including a .ebextensions file in the deployment war that would overwrite the server.xml file but this runs the risk of AWS changing something else in server.xml in the future. Another issue is I want the same app version (build from jenkins) to work in my dev environment as well as other EB environments that don't necessarily need/have ssl enabled.

So I changed course and implemented a servlet filter which uses two headers that the load balancer provides

  • X-Forwarded-Proto
  • x-forwarded-host

if X-Forward-Proto == http then you know you need to forward, x-forward-host is needed to construct the full url for redirection (as least that's how I ended up doing it). Here is the filter with environment specific control over it using a customer PropertiesHelper

public class RedirectFilter implements Filter {
    boolean firstTime = true;
    boolean redirect = false;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

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

        if (firstTime) {
            PropertiesHelper propertiesHelper = SpringApplicationContext.getPropertiesHelper();
            redirect = propertiesHelper.getBooleanProperty("redirectHttp");
            firstTime = false;
        }

        if (!redirect) {
            chain.doFilter(request, response);
            return;
        }

        String protocol = req.getHeader("X-Forwarded-Proto");
        if (null != protocol && protocol.equals("http")) {
            String host = req.getHeader("x-forwarded-host");
            String requestURI = req.getRequestURI();
            String redirectUrl = "https://" + host + requestURI;

            res.sendRedirect(redirectUrl);
            return;
        }
        chain.doFilter(req, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }
}

You enable the filter with entries in the web.xml, making sure it is in the proper order with other filters you have

<filter>
    <filter-name>httpsRedirectFilter</filter-name>
    <filter-class>com.cars.platform.util.RedirectFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>httpsRedirectFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Lastly you do need to enable both http and https (port 443) on the load balancer




回答2:


If I understand you correctly, you only want the standard HTTPS port 443 to be used by the Elastic Load Balancer and not the additionally configure port 8443?

This is easily possible by clicking the Remove button int he Action column within the listener table of the first image you provided. The entire process, including options to achieve the same goal by different means, is also detailed and illustrated in Deleting a Listener from Your Load Balancer:

The following sections include instructions for deleting a listener from the specified port of your existing load balancer using the AWS Management Console, command line interface (CLI), or the Query API. In this example, you delete a listener from port 80 of your load balancer MyLoadBalancer.




回答3:


I caught the same problem, tried googling but without luck, finally I got the answer.

Before things goes fine, I have the following port redirection settings:

redirect 192.168.1.177:80 to 127.0.0.1:8080  
redirect 192.168.1.177:443 to 127.0.0.1:8443

And there in web.xml is such a piece of code:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>SecuredResources</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

When I was visiting http://192.168.1.177/, Tomcat redirected the request to https://192.168.1.177:8443/ which is not the one https://192.168.1.177/ as I expected.

I found that there is a attribute redirectPort of element <Connector/> in server.xml, When I tried setting the redirectPort to 443 of HTTP connector,

from

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

to

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="443"/>

then after restarting Tomcat, voilà, it works.



来源:https://stackoverflow.com/questions/13226254/how-to-redirect-http-request-to-https-on-java-application-installed-on-amazon-el

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