-
1. Re: SSL Encryption and HTTP Basic Authentication on switchyard exposed soap services
amit4497 Jun 8, 2017 8:07 AM (in response to amit4497)1 of 1 people found this helpfulWell, 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.