1 Reply Latest reply on Jun 8, 2017 8:07 AM by Amit Kumar

    SSL Encryption and HTTP Basic Authentication on switchyard exposed soap services

    Amit Kumar Newbie

      Hi All,

       

       

      I have two SOAP services (TroubleSupervision and TroubleNotification) exposed in my switchyard application as shown below:

       

       

       

      Capture.PNG

       

       

      I want to host TroubleNotification service on HTTPS and also would like to enable HTTP Basic Authentication for the same. However same I don't want to do with my other service TroubleSupervision.

      Is there any way to achieve it by doing any configuration in standalone.xml or by adding an interceptor in between the exposed service and my bean class ?

      I tried searching google but couldn't find anything relevant which could help me to move forward.

       

       

      Please let me know in case my question is not clear or you want any kind of information.

       

       

      Thanks in advance!!!

        • 1. Re: SSL Encryption and HTTP Basic Authentication on switchyard exposed soap services
          Amit Kumar Newbie

          Well, finally I know how to enable HTTPS on JBoss and provide a HTTP Basic Authentication check for my SwitchYard exposed service.

           

          HTTPS Configuration

           

          To host a web service on HTTPS in JBoss, web subsystem has to modified in standalone.xml/domain.xml.

          <subsystem xmlns="urn:jboss:domain:web:1.4" default-virtual-server="default-host" native="false">
          

           

          Before we start web subsystem modification, we should have a keystore. Keystore could be a self-signed one or could be from a certified authority(CA). In my case, I have generated a self-signed keystore.

          Once we have a valid keystore, we can modify the web subsystem using CLI or we can directly modify the standalone.xml.

           

          Below connector can be added to the web subsystem. We can remove the http connector in case http support is not required.

           

          <subsystem xmlns="urn:jboss:domain:web:1.4" default-virtual-server="default-host" native="false">
           <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
           <connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" enable-lookups="false" secure="true">
            <ssl name="tomcat-ssl" key-alias="selfsigned" password="password" certificate-key-file="/root/keystore.jks" protocol="TLSv1.2" verify-client="true" ca-certificate-file="/root/truststore.jks"/>
           </connector>
           <connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp"/>
           <virtual-server name="default-host" enable-welcome-root="true">
            <alias name="localhost"/>
             <alias name="example.com"/>
           </virtual-server>
          </subsystem>
          

          That's it. Just restart the Jboss server and you can access your web service hosted on HTTPS on 8443 port (which is a default port. In case any offset is applied then the port will be 8443+offset).

           

          HTTP Basic Authentication

           

          To enable HTTP Basic Authentication for a client, an interceptor has to be introduced between the exposed service and the implementation bean.

           

          HttpBasicAuthenticationInterceptor.java

          package com.interceptor;
          
          
          import java.net.HttpURLConnection;
          import java.util.HashMap;
          import java.util.Map;
          import javax.annotation.PreDestroy;
          import javax.xml.namespace.QName;
          import org.apache.cxf.binding.soap.interceptor.SoapHeaderInterceptor;
          import org.apache.cxf.configuration.security.AuthorizationPolicy;
          import org.apache.cxf.interceptor.Fault;
          import org.apache.cxf.message.Message;
          
          public class HttpBasicAuthenticationInterceptor extends SoapHeaderInterceptor {
           /** Map of allowed users to this system with their corresponding passwords. */
           private Map<String, String> users;
              
           public Map<String, String> getUsers() {
                  return users;
              }
           
             /* @Required
              public void setUsers(Map<String, String> users) {
                  this.users = users;
              }*/
           String username = "";
           String password = "";
              public HttpBasicAuthenticationInterceptor() {
               username = "JBOSS";
               password = "CHANGE_IT";
               
               // initialize the map and its data
            users = new HashMap<String, String>();
            users.put(username, password);
              }
              
              @Override 
              public void handleMessage(Message message) throws Fault {
               
               // This is set by CXF
                  AuthorizationPolicy policy = (AuthorizationPolicy) message.get(AuthorizationPolicy.class);
                  
                  // If the policy is not set, the user did not specify credentials
                  // A 401 is sent to the client to indicate that authentication is required
                  if (policy == null) {
                      System.out.println("HttpBasicAuthenticationInterceptor-User attempted to log in with no credentials "+policy);
                      
                      /*sendErrorResponse(message, HttpURLConnection.HTTP_UNAUTHORIZED);
                      return;*/
                      Fault fault = new Fault("User attempted to log in with no credentials", java.util.logging.Logger.getGlobal());
                      fault.setStatusCode(HttpURLConnection.HTTP_UNAUTHORIZED);
                      fault.setFaultCode(new QName(String.valueOf(HttpURLConnection.HTTP_UNAUTHORIZED)));
                      throw fault;
                  }
                          
                  // Verify the password
                  String realPassword = users.get(policy.getUserName());
                  if (realPassword == null || !realPassword.equals(policy.getPassword())) {
                      System.out.println("HttpBasicAuthenticationInterceptor-Invalid username or password for user: " + policy.getUserName());
                      
                      Fault fault = new Fault("Invalid username or password for user : "+policy.getUserName(), java.util.logging.Logger.getGlobal());
                      fault.setStatusCode(HttpURLConnection.HTTP_FORBIDDEN);
                      fault.setFaultCode(new QName(String.valueOf(HttpURLConnection.HTTP_FORBIDDEN)));
                      throw fault;
                   }
              }
          }
              
           
          

          When a client invokes your exposed service, he need to pass a valid username and password on http header so that your interceptor can validate the same.

          1 of 1 people found this helpful