4

I want make HTTP Redirect work on WebSphere Application Server Liberty Profile (WLP). For example:-

When user types: http://localhost:8080/helloworld, the browser should automatically go (be redirected) to https://localhost:9443/helloworld

To achieve this, I followed this document, Section 6.2, page no. 136.

Below is the sample server.xml and web.xml:-

server.xml

<server description="new server">

<!-- Enable features -->
<featureManager>
    <feature>jsp-2.2</feature>
    <feature>wab-1.0</feature>
    <feature>jaxrs-1.1</feature>
    <feature>blueprint-1.0</feature>
    <feature>localConnector-1.0</feature>
    <feature>ssl-1.0</feature>
    <feature>appSecurity-2.0</feature>
</featureManager>

<httpEndpoint host="localhost" httpPort="8081" httpsPort="9442" id="defaultHttpEndpoint">
</httpEndpoint>

<applicationMonitor updateTrigger="mbean"/>
<keyStore id="defaultKeyStore" password="{xor}Lz4sLCgwLTtu"/>

<application id="Hello.app" location="Hello.app.eba" name="Hello.app" type="eba"/>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>Hello</display-name>

    <security-constraint>
        <display-name>HTTPS Redirect Security Constraint</display-name>
        <web-resource-collection>
            <web-resource-name>Sample Web Service service</web-resource-name>
            <url-pattern>/Hello</url-pattern>
            <http-method>GET</http-method>

        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
</web-app>

Have removed the <servlet> and <servlet-mapping> tag for brevity.

Below are the versions that I am using:- Java 7, WLP 8.5.5, Eclipse Juno, Google Chrome.

Any help, guidelines on why HTTPS redirect is not working will be much appreciated.

Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265
Anuroop
  • 993
  • 3
  • 13
  • 25

3 Answers3

3

I suspect the problem is in your security-constraint. Looking at it I would suggest changing your url-pattern to be:

/helloworld

rather than:

/Hello

If you want to match multiple resources you can use wildcards such as:

  1. /* - matches everything
  2. /helloworld/* - matches everything that has helloworld/ in the url path
  3. *.jsp - matches all files with a jsp extension
Alasdair
  • 3,071
  • 15
  • 20
  • Thanks for the help. But the real problem it seems was that I missed an important tag. Will post the answer after verifying my theory. – Anuroop Jul 08 '13 at 11:59
  • @Anuroop Your theory is unfortunately wrong, as you don't need auth-constraint just for https redirection. You also don't need steps steps 1 and 2 from your solution nor login-config. As login is not required at all for redirection. – Gas Nov 11 '14 at 19:44
3

To make HTTPS Redirect work on WLP, following points should be taken care of:-

  1. Add users, roles, and passwords in server.xml of WLP.
  2. Bind the application to the security role.
  3. Add appSecurity-2.0 feature in server.xml of WLP.
  4. Add following tags in web.xml
    1. <login-config>
    2. <security-constraint>
    3. <security-constraint><web-resource-name></security-constraint>
    4. <security-constraint><auth-constraint></security-constraint>
    5. <security-constraint><user-data-constraint></security-constraint>

Below are the steps in detail:-

1. Add users, roles, and passwords in server.xml of WLP.

<basicRegistry id="MyRegistry">
    <user password="{xor}Mjo6MT4z" name="anuroop" />
    <group name="MyGroup">
        <member name="anuroop" />
    </group>
</basicRegistry>

2. Bind the application to the security role.

<application id="Hello.app" location="Hello.app.eba" name="Hello.app" type="eba">
    <application-bnd>
        <security-role name="Manager">
        <group name="MyGroup" />
    </security-role>
    </application-bnd>
</application>

3. Add appSecurity-2.0 feature in server.xml of WLP.

<featureManager>
    <feature>appSecurity-2.0</feature>
</featureManager>

4.1, 4.2, 4.3, 4.4, 4.5

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>BasicRegistry</realm-name>
    <form-login-config>
        <form-login-page>/Login.jsp</form-login-page>
        <form-error-page>/LoginError.jsp</form-error-page>
    </form-login-config>
</login-config>

<security-constraint>

        <display-name>HTTPS Redirect Security Constraint</display-name>
        <web-resource-collection>
            <web-resource-name>Sample Web Service service</web-resource-name>
            <url-pattern>/Hello</url-pattern>
            <http-method>GET</http-method>
        </web-resource-collection>

    <auth-constraint>
        <role-name>Manager</role-name>
    </auth-constraint>

    <user-data-constraint>
    <description>Ensure to allow only confidential communication</description>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>

</security-constraint>
Anuroop
  • 993
  • 3
  • 13
  • 25
  • 1
    Seems like a bug in WLP. You shouldn't need a user just to perform the redirect. – Archimedes Trajano May 10 '17 at 14:08
  • In addition with WebSphere Classic 9, when doing it with just the security-constraint it will also require a login so it will not allow anonymous access. Seems that the safest way to support anonymous websphere redirects is through a filter as noted by @Vince Thyng – Archimedes Trajano May 10 '17 at 14:23
0

I solved this a different way, but I think the accepted answer may be better. You can write a servlet filter and then modify the web.xml to associate it with a path.

The web.xml code:

  <web-app id="WebApp">
      <filter>
        <filter-name>HTTPSFilter</filter-name>
        <filter-class>
        HTTPSFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HTTPSFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    ...
 </web-app>

The filter code:

public class HTTPSFilter implements Filter {
    public void doFilter(ServletRequest req, 
                         ServletResponse res,
                         FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        // Forward to HTTPS if insecure HTTP was used
        if(!req.getScheme().startsWith("https")) {
            // Modify the Response object to be the SSL version of the URL
            String host         = request.getLocalName();

            String URI         = request.getRequestURI();
            if(URI == null) { URI = ""; }

            String queryString  = request.getQueryString();
            if(queryString == null) { queryString = ""; }

            response.sendRedirect("https://" + host + ":9443" + URI + ("".equalsIgnoreCase(queryString) ? "":"?") + queryString);
        }

        chain.doFilter(req, res);
    }
    public void init(FilterConfig config) throws ServletException {
    }
    public void destroy() {
    }
}
emmanuel
  • 9,607
  • 10
  • 25
  • 38
  • Using web.xml is correct way, since it will work in any appserver. You are doing by hand what should be done by container. In addition you hardcoding https port, so your filter will fail in case someone would need to change the default port. – Gas Nov 11 '14 at 19:41