Securing EJBs with SSL on Wildfly 18
Wildfly has a new security framework called Elytron, which brings significant changes to how you configure Wildfly to make use of SSL for EJB connections.
This post details the configuration required and shows a simple client and EJB project to demonstrate the steps needed to secure your EJB calls.
The most recent versions of Wildfly bring with them a new security framework called Elytron , which brings significant changes to how you configure Wildfly to make use of SSL for EJB connections.
This post details the configuration required and shows a simple client and EJB project to demonstrate the steps needed to secure your EJB calls.
First create the Server and Client keystore and truststore files using the script below.
#!/bin/sh
# script for re-generating the keystores and truststores needed for SSL connector
# Create server keystore - file server.keystore
keytool -genkey -v -alias jbossalias -keyalg RSA -keysize 1024 -keystore server.keystore -validity 3650 -keypass 123456 -storepass 123456 -dname "cn=Server Administrator,o=Acme,c=GB"
# Export Server's Public Key - file server.cer
keytool -export -keystore server.keystore -alias jbossalias -file server.cer -keypass 123456 -storepass 123456
# Export Client Key Store - file client.keystore
keytool -genkey -v -alias clientalias -keyalg RSA -keysize 1024 -keystore client.keystore -validity 3650 -keypass abcdef -storepass abcdef -dname "cn=Server Administrator,o=Acme,c=GB"
# Exporting Client's Public Key - file client.cer
keytool -export -keystore client.keystore -alias clientalias -file client.cer -keypass abcdef -storepass abcdef
# Importing Client's Public key into server's truststore
keytool -import -v -trustcacerts -alias clientalias -file client.cer -keystore server.truststore -keypass 123456 -storepass 123456
# Importing Server's Public key into client's truststore
keytool -import -v -trustcacerts -alias jbossalias -file server.cer -keystore client.truststore -keypass abcdef -storepass abcdef
Generate Keypairs Then copy the server.keystore
and server.truststore
files to the Wildfly configuration directory, such as /wildfly-18.0.1.Final/standalone/configuration
.
Then in the Wildfly CLI run the following commands to add the server keystore and trust manager.
#Script to create Elytron keystore-trust-manager-server-ssl-context using the default ApplicationDomain that ships with Wildfly
connect
/subsystem=elytron/key-store=server-key-store:add(path=server.keystore, relative-to=jboss.server.config.dir, credential-reference={clear-text=123456}, type=JKS)
/subsystem=elytron/key-store=server-trust-store:add(path=server.truststore, relative-to=jboss.server.config.dir, credential-reference={clear-text=123456}, type=JKS)
/subsystem=elytron/key-manager=example-key-manager:add(key-store=server-key-store, credential-reference={clear-text=123456})
/subsystem=elytron/trust-manager=example-trust-manager:add(key-store=server-trust-store)
/subsystem=elytron/server-ssl-context=example-ssl-context:add(trust-manager=example-trust-manager, key-manager=example-key-manager, need-client-auth=true, want-client-auth=true)
batch
/subsystem=undertow/server=default-server/https-listener=https:undefine-attribute(name=security-realm)
/subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=ssl-context,value=example-ssl-context)
run-batch
reload
Add server keystore & SSL context Then in the Wildfly configuration file, we need to add a new remoting connector to make use of the https
connection.
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
<http-connector name="https-remoting-connector" connector-ref="https" security-realm="ApplicationRealm"/>
</subsystem>
Remoting connector configuration Finally, we need to add a user to Wildfly for the EJB connection and authentication.
$ ./add-user.sh -a -u 'sslUser' -p 'sslUserPass123!'
Add wildfly user That's it for the Widlfly server setup.
In your EJB project, create a basic EJB like the following.
package org.slsltest;
import javax.ejb.Remote;
@Remote
public interface Calculator {
float calculateInterest(long money);
}
Calculator.java package org.slsltest;
import javax.ejb.Stateless;
/**
* Session Bean implementation class CalculatorEJB
*/
@Stateless
public class CalculatorEJB implements Calculator {
float interest = 5;
@Override
public float calculateInterest(long money) {
return money * (1 + (interest / 100));
}
}
CalculatorEJB.java Package the EJB project in an EAR or similar and deploy to your Wildfly server.
In your client project, copy the client.keystore
and client.truststore
files you created back at the start to the root directory. Then in a resources/META-INF
directory, create the following wildfly-config.xml
file.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<authentication-client xmlns="urn:elytron:1.0">
<authentication-rules>
<rule use-configuration="default" />
</authentication-rules>
<authentication-configurations>
<configuration name="default">
<sasl-mechanism-selector
selector="DIGEST-MD5" />
<set-user-name name="sslUser" />
<credentials>
<clear-password password="sslUserPass123!" />
</credentials>
</configuration>
</authentication-configurations>
<key-stores>
<key-store name="client-keystore" type="JKS">
<file name="./client.keystore" />
<key-store-clear-password password="abcdef" />
</key-store>
<key-store name="client-truststore" type="JKS">
<file name="./client.truststore" />
</key-store>
</key-stores>
<ssl-contexts>
<ssl-context name="client-ssl-context">
<trust-store key-store-name="client-truststore" />
<key-store-ssl-certificate
key-store-name="client-keystore" alias="clientalias">
<key-store-clear-password
password="abcdef" />
</key-store-ssl-certificate>
</ssl-context>
</ssl-contexts>
<ssl-context-rules>
<rule use-ssl-context="client-ssl-context" />
</ssl-context-rules>
</authentication-client>
<jboss-ejb-client
xmlns="urn:jboss:wildfly-client-ejb:3.0">
<connections>
<connection uri="remote+https://127.0.0.1:8443" />
</connections>
</jboss-ejb-client>
</configuration>
wildfly-config.xml Then add the jboss-client.jar
to your project's classpath (found in /wildfly-18.0.1.Final/bin/client
).
Finally create a class like the below.
package org.ssltest;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.slsltest.Calculator;
public class SslTest {
public static void main(String[] args) throws Exception {
Calculator calculator = lookupCalculatorEJB();
final long amount = 1000L;
System.out.println("Calculating interest on " + amount);
float total = calculator.calculateInterest(amount);
System.out.println("Final amount = " + total);
}
private static Calculator lookupCalculatorEJB() throws NamingException {
final Hashtable<String, String> jndiProperties = new Hashtable<>();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
final Context context = new InitialContext(jndiProperties);
return (Calculator) context.lookup("ejb:SslTestEar/SslTestEjb/CalculatorEJB!org.slsltest.Calculator");
}
}
SslTest.java And that's it. Just run your project.