This is a complete tutorial to show how you can configure SSL/HTTPS support for your WildFly 8/9/10/11 or later server.

Generally speaking, to configure SSL/HTTPS you can either use the pure JSSE implementation (and the keytool utility) or a native implementation based on OpenSSL. We will cover at first the JSSE implementation with keytool. Later we will show how to enable OpenSSL on WildFly 11

Create server and client certificates

The keytool utility stores the keys and certificates in a file termed as keystore, a repository of certificates used for identifying a client or a server. Typically, a keystore contains one client or one server's identity, which are protected by using a password.

You can create a certificate for your server using the following command:

$ keytool -genkey -keyalg RSA -keystore server.keystore -storepass secret -keypass secret -validity 365  -dname "cn=Server Administrator,o=Acme,c=GB" 

This command created the keystore named server.keystore in the working directory, and assigns it the password secret . It generates a public/private key pair for the entity whose "distinguished name" has a common name of Server Administrator , organization of Acme and two-letter country code of GB.

Now let's copy this keystore into the configuration folder of the application server:

$ cp server.keystore $JBOSS_HOME/standalone/configuration

If you only need a one-way authentication (Server-->Client) then you are done.

Otherwise, if you need a two-way authentication (Server<-->Client) then we need to create as well the client certificates and export them to create a truststore.

The following command, will create the client certificate, which is used to authenticate against the server when accessing a resource through SSL

$  keytool -genkey -keystore client.keystore -storepass secret -validity 365 -keyalg RSA -keysize 2048 -storetype pkcs12 -dname "cn=Desktop user,o=Acme,c=GB" 

Now export the client certificate in a file called client.crt:

$ keytool -exportcert -keystore client.keystore  -storetype pkcs12 -storepass secret -keypass secret -file client.crt
Certificate stored in file <client.crt>

And then import the client certificate into the truststore of the client. At the end of it, you will be requested to trust the certificate:

$ keytool -import -file client.crt -alias quickstartUser -keystore client.truststore -storepass secret
Owner: CN=Desktop user, O=Acme, C=GB
Issuer: CN=Desktop user, O=Acme, C=GB
Serial number: 7dc12bc6
Valid from: Thu Feb 15 11:36:42 CET 2018 until: Fri Feb 15 11:36:42 CET 2019
Certificate fingerprints:
	 MD5:  1A:A8:AD:07:A0:B2:9B:F6:E3:C7:0B:9E:C0:F0:50:2C
	 SHA1: B3:FB:3D:BD:91:CD:B3:ED:F9:99:9D:2E:E6:3D:AC:13:BA:2A:50:6B
	 SHA256: D4:E7:17:4C:43:5E:2A:F4:9B:E5:C3:FC:18:80:B2:30:32:CA:31:AE:5F:9B:A5:67:F0:BB:AB:20:D5:77:9A:C2
	 Signature algorithm name: SHA256withRSA
	 Version: 3

Extensions: 

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 53 D2 1E 96 CC E1 CB A4   6B 49 C9 73 EB 43 E2 33  S.......kI.s.C.3
0010: E0 2B B1 04                                        .+..
]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore

Last step, if you want to import the client certificate in your browser, then we will use the keytool utility to export client certificate to pkcs12 format.

The PKCS#12 is a binary format for storing the server certificate, any intermediate certificates, and the private key into a single encryptable file. These files are usually found with the extensions .pfx and .p12 and are typically used on Windows machines to import and export certificates and private keys.

$  keytool -importkeystore -srckeystore client.keystore -srcstorepass secret -destkeystore clientCert.p12 -srcstoretype PKCS12 -deststoretype PKCS12 -deststorepass secret
Entry for alias mykey successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

Now copy all keystores into the configuration folder of the application server:

$ cp *.keystore $JBOSS_HOME/standalone/configuration

Importing certificates on your browser

If you want to use an application which uses mutual SSL then you have to import the certificates in your Browser. Every browser uses a different set of menu to import the certificates. For Chrome, click the Chrome menu icon (3 dots) in the upper right on the browser toolbar and choose Settings.

Scroll to the bottom of the page and click on the Advanced link to reveal the advanced settings. Search for the Manage Certificates line under Privacy and security and then click on it.

SSL tutorial wildfly secure jboss https

In the Manage certificates screen, select the Your Certificates tab and click on the Import button. Select the p12 file. You will be prompted to enter the password: secret.

The client certificate is now installed in the Google Chrome browser.

SSL tutorial wildfly secure jboss https

Configuring One-Way SSL/HTTPS on WildFly 11 or newer

When using WildFly 11 or newer you can either use Elytron or the Legacy SSL configuration. To verify which one is the default one check and see if the https-listener is configured to use a legacy security realm for its SSL configuration:

/subsystem=undertow/server=default-server/https-listener=https:read-attribute(name=security-realm)
{
    "outcome" => "success",
    "result" => "ApplicationRealm"
}

The above command shows that the https-listener is configured to use the legacy ApplicationRealm for its SSL configuration.Therefore we will undefine the security-realm attribute in the https-listener as Undertow cannot reference both a legacy security realm and an ssl-context in Elytron.

The following CLI batch script will Add the keystores, key manager,and ssl context configuration in the elytron subsystem, removing the reference to the Undertow's https-listener.

batch

/subsystem=elytron/key-store=demoKeyStore:add(path=server.keystore,relative-to=jboss.server.config.dir, credential-reference={clear-text=secret},type=JKS)
 
/subsystem=elytron/key-manager=demoKeyManager:add(key-store=demoKeyStore,credential-reference={clear-text=secret})
  
/subsystem=elytron/server-ssl-context=demoSSLContext:add(key-manager=demoKeyManager,protocols=["TLSv1.2"])
 
# This is only needed if WildFly uses by default the Legacy security realm
/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=demoSSLContext)

run-batch

reload

That's all. Now if you try to access a Web application through the https://host:8443 address, you will be informed that you are using a self-signed certificate. If you add an exception to the browser you will be running through the SSL channel, with your certificate:

SSL tutorial wildfly secure jboss https

In terms of configuration, here is the tls section which has been added to WildFly:

<tls>
	<key-stores>
	    <key-store name="demoKeyStore">
		<credential-reference clear-text="secret"/>
		<implementation type="JKS"/>
		<file path="server.keystore" relative-to="jboss.server.config.dir"/>
	    </key-store>
	</key-stores>
	<key-managers>
	    <key-manager name="demoKeyManager" key-store="demoKeyStore">
		<credential-reference clear-text="secret"/>
	    </key-manager>
	</key-managers>
	<server-ssl-contexts>
	    <server-ssl-context name="demoSSLContext" protocols="TLSv1.2" key-manager="demoKeyManager"/>
	</server-ssl-contexts>
</tls>

And the corresponding undertow section:

  <subsystem xmlns="urn:jboss:domain:undertow:4.0">
            <buffer-cache name="default"/>
            <server name="default-server">
                <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
                <https-listener name="https" socket-binding="https" ssl-context="demoSSLContext" enable-http2="true"/>
                <host name="default-host" alias="localhost">
                    <location name="/" handler="welcome-content"/>
                    <filter-ref name="server-header"/>
                    <filter-ref name="x-powered-by-header"/>
                    <http-invoker security-realm="ApplicationRealm"/>
                </host>
            </server>

Running mutual SSL configuration:

Mutual SSL provides the same security as SSL, with the addition of authentication and non-repudiation of the client authentication, using digital signatures. When mutual authentication is used, the server would request the client to provide a certificate in addition to the server certificate issued to the client. Mutual authentication requires an extra round trip time for client certificate exchange. In addition, the client must buy and maintain a digital certificate. We can secure our war application deployed over WildFly with mutual(two-way) client certificate authentication and provide access permissions or privileges to legitimate users.

In addition to the Keystore, we need to configure the TrustStore, setting in the SSL Context that the Client Authentication is needed as well:

batch

# Add the keystores, key manager, trust manager and ssl context configuration in the elytron subsystem
/subsystem=elytron/key-store=demoKeyStore:add(path=server.keystore,relative-to=jboss.server.config.dir,type=JKS,credential-reference={clear-text=secret})
/subsystem=elytron/key-store=demoTrustStore:add(path=client.truststore,relative-to=jboss.server.config.dir,type=JKS,credential-reference={clear-text=secret})
/subsystem=elytron/key-manager=demoKeyManager:add(key-store=demoKeyStore,credential-reference={clear-text=secret})
/subsystem=elytron/trust-manager=demoTrustManager:add(key-store=demoTrustStore)
/subsystem=elytron/server-ssl-context=demoSSLContext:add(key-manager=demoKeyManager,trust-manager=demoTrustManager,protocols=[TLSv1.2],need-client-auth=true)

# This is only needed if WildFly uses by default the Legacy security realm 
/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=demoSSLContext)

run-batch

reload

In terms of configuration, you can enforce mutual SSL authentication in an application by declaring its transport as confidential in web.xml:

<security-constraint>

  <web-resource-collection>
      <url-pattern>/*</url-pattern>
  </web-resource-collection>

  <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>

</security-constraint>

Configuring OpenSSL as provider

When using Elytron for SSL/HTTPS you can opt for two different providers:

<providers>
        <aggregate-providers name="combined-providers">
            <providers name="openssl"/>
            <providers name="elytron"/>
        </aggregate-providers>
        <provider-loader name="elytron" module="org.wildfly.security.elytron"/>
        <provider-loader name="openssl" module="org.wildfly.openssl"/>
</providers> 

In order to switch to OpenSSL, at first set your security Realm to use OpenSSL TSL as protocol:

/core-service=management/security-realm=ApplicationRealm/server-identity=ssl:write-attribute(name=protocol, value=openssl.TLS)

This will show in your console that the OpenSSL protocol has been loaded:

12:08:00,027 INFO  [org.wildfly.openssl.SSL] (MSC service thread 1-7) WFOPENSSL0002 OpenSSL Version OpenSSL 1.0.2j-fips  26 Sep 2016

Next, we need to change the ordering of the providers in the elytron combined-providers, which means that OpenSSL will now take precedence:

/subsystem=elytron/aggregate-providers=combined-providers:list-add(index=0, name=providers, value=openssl)
/subsystem=elytron/aggregate-providers=combined-providers:list-remove(index=2, name=providers)

Configuring SSL using Legacy mode

If you are using an earlier version of WildFly (8/9/10) or you simply don't want to use Elytron as security mechanism, you can still use the Legacy security for securing your HTTP communication.

Start by creating a Security Realm which will contain the keystore and trustore references

/core-service=management/security-realm=SSLRealm:add

Next, for one-way SSL, set the path to the keystore, along with the keystore path and password:

/core-service=management/security-realm=SSLRealm/server-identity=ssl:add(keystore-path="server.keystore", keystore-relative-to="jboss.server.config.dir", keystore-password="secret")

If you are using mutual authentication, you will need to set the path to the truststore, along with the its path and password:

/core-service=management/security-realm=SSLRealm/authentication=truststore:add(keystore-password="secret",keystore-path="server.truststore",keystore-relative-to="jboss.server.config.dir")

Finally, set the value of Undertow's https listener to your Security Realm:

/subsystem=undertow/server=default-server/https-listener=default-https:write-attribute(name=security-realm,value=SSLRealm)
0
0
0
s2smodern

Related articles available on mastertheboss.com

JBoss security framework

Security is a fundamental part of any enterprise application .The

Configure JBoss with LDAP

In this tutorial we will show how to connect JBoss AS 7 (and earl

Configuring Single Signon on JBoss AS 7

This tutorial describes how to configure Single Signon for a JBos

Securing AS 7 applications using the ApplicationRealm

JBoss AS 7 and the EAP 6 provide out of the box a Security Domain

Securing access to JBoss-WildFly Management console

In this tutorial we will demonstrate how to secure access to the

Configuring a MongoDB Login Module

Creating a Login Module with JBoss AS 7 or WildFly can be done by

W

i

l

d

F

l

y

 

c

h

e

a

t

s

h

e

e

t