How to configure an Elytron JDBC Realm on WildFly

In this tutorial we will learn how to configure an Elytron JDBC Realm on WildFly 11 using both the Web console of the application server and the Command Line Interface (CLI).

Prerequisites

  • MySQL Database
  • WildFly 11 or newer

The first thing we will do is creating a Datasource which will connect to an existing MySQL Database

If you don’t have an available MySQL Database, you can easily complete this tutorial by starting MySQL as Docker container:

$ docker run -d --name mysql -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=demodb -e MYSQL_ROOT_PASSWORD=secret mysql

Now move to the WildFly Web Console and Create a new Datasource using the DataSource wizard as in the following example.

Choose the Database:

eyltron tutorial jboss wildfly

Enter the DataSource Attributes:

eyltron tutorial jboss wildfly

Pickup the Driver to be used (in our example we have deployed the MySQL Driver)

eyltron tutorial jboss wildfly

Finally, complete the Datasource configuration entering the Connection Settings

eyltron tutorial jboss wildfly

Configuring Elytron JDBC Realm

Next step will be configuring the JDBC Realm for Elytron.

A JDBCSecurity realm is a security realm implementation backed by a database based whose implementation is the class org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm

Move in the Configuration > Subsystems > Security – Elytron window:

eyltron tutorial jboss wildfly

Click on the Add button. You will need to define a JDBC Realm as in the following picture. The JDBC Realm needs to be bound against the MySQLDS Datasource we have created.

eyltron tutorial jboss wildfly

WildFly Web console is able to autocomplete the text field which reference another element of the configuration. For example, just click Arrow-Down key on the Principal Query Datasource and you will be able to browse across the available Datasources

As a result, you should have now a JDBC Realm available in your configuration:

eyltron tutorial jboss wildfly

Now we need adding an Elytron Security Domain to reference our JDBC Realm. Move into the Configuration > Subsystems > Security – Elytron > Settings: Other window:

eyltron tutorial jboss wildfly

Click on Add and complete the Security Domain UI with the Name and Realm name:

eyltron tutorial jboss wildfly

As a result, you should be able to see the “jdbcdomain” in your SecurityDomain window:

eyltron tutorial jboss wildfly

Now we will need to add a new HTTP Server authentication mechanism in your Elytron configuration. Move into the Configuration > Subsystems > Security – Elytron > Settings: Factory/Transformer window:

eyltron tutorial jboss wildfly

Click on Add and define a new HTTP Authentication based on the “global” HTTP server mechanism factory and the “jdbcdomain”:

eyltron tutorial jboss wildfly

Now the last step will be registering the Security Domain into Undertow web server. Move into the Configuration > Subsystems > Web/HTTP – Undertow > HTTP window and select the Application security Tab:

eyltron tutorial jboss wildfly

Click on Add. Bind the Security Domain the the Http autentication Factory we have created on the Elytron subsystem:

eyltron tutorial jboss wildfly

Now if you try to deploy an application bound to the “web-security-domain” security domain:

<jboss-web>
    <security-domain>web-security</security-domain>
</jboss-web>

As a result, you will receive a BASIC HTTP Authentication challenge:

elytron wildfly tutorial

Creating a JDBC Security realm with the CLI

We will show here how to configure the Elytron JDBC Security Realm using the Command Line Interface (CLI).

Start the server as follows:

$ ./standalone.sh

The prerequisite is that you have already configured a MySQLPool Datasource which in turn references a MySQL database where user names and password are stored in the USERS table

Start by creating a new JDBC realm that refers our MySQLPool. For the sake of simplicity, we will be using a clear text password strategy.

/subsystem=elytron/jdbc-realm=jdbcRealm:add(principal-query=[{sql="SELECT passwd from USERS where login = ? ",data-source=MySQLPool,clear-password-mapper={password-index="1"}}])

/subsystem=elytron/security-domain=jdbcdomain:add(default-realm=jdbcRealm,realms=[{realm="jdbcRealm"}])

Next, since this security domain will use HTTP Basic authentication, we will define a new HTTP Server Authentication policy based on the jdbcdomain security domain and named http-db-auth:

/subsystem=elytron/http-authentication-factory=http-db-auth:add(security-domain=jdbcdomain,mechanism-configurations=[{mechanism-name=BASIC,mechanism-realm-configurations=[realm-name="Secured by Elytron"]}],http-server-mechanism-factory=global)

In order to propagate the HTTP Authentication policy with Undertow, which governs your web applications, a component named HTTP Authenticating factory is needed. This will eventually trigger the HttpServerAuthenticationMechanism from within the Undertow web server. Here is the command needed to create an HTTP Authenticating factory:

/subsystem=undertow/application-security-domain=web-security-domain:add(http-authentication-factory=http-db-auth)

Reload your server configuration for the changes to take effect. In terms of configuration, the following XML section will be included in your elytron subsystem:

<subsystem xmlns="urn:wildfly:elytron:1.0">
    <security-domains>
        <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="login-permission-mapper">
            <realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
        </security-domain>
        <security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="login-permission-mapper">
            <realm name="ManagementRealm" role-decoder="groups-to-roles"/>
        </security-domain>
        <security-domain name="jdbcdomain" default-realm="jdbcRealm">
            <realm name="jdbcRealm"/>
        </security-domain>
    </security-domains>
    <security-realms>
        <jdbc-realm name="jdbcRealm">
            <principal-query sql="SELECT passwd from USERS where login = ? " data-source="MySQLPool">
                <clear-password-mapper password-index="1"/>
            </principal-query>
        </jdbc-realm>
        <properties-realm name="ApplicationRealm">
            <users-properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
            <groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
        </properties-realm>
        <properties-realm name="ManagementRealm">
            <users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
            <groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
        </properties-realm>
    </security-realms>
    <mappers>
        <constant-permission-mapper name="login-permission-mapper">
            <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
        </constant-permission-mapper>
        <simple-role-decoder name="groups-to-roles" attribute="groups"/>
    </mappers>
    <http>
        <http-authentication-factory name="management-http-authentication" http-server-mechanism-factory="global" security-domain="ManagementDomain">
            <mechanism-configuration>
                <mechanism mechanism-name="BASIC">
                    <mechanism-realm realm-name="Management Realm"/>
                </mechanism>
            </mechanism-configuration>
        </http-authentication-factory>
        <http-authentication-factory name="application-http-authentication" http-server-mechanism-factory="global" security-domain="ApplicationDomain">
            <mechanism-configuration>
                <mechanism mechanism-name="BASIC">
                    <mechanism-realm realm-name="Application Realm"/>
                </mechanism>
                <mechanism mechanism-name="FORM"/>
            </mechanism-configuration>
        </http-authentication-factory>
        <http-authentication-factory name="http-db-auth" http-server-mechanism-factory="global" security-domain="jdbcdomain">
            <mechanism-configuration>
                <mechanism mechanism-name="BASIC">
                    <mechanism-realm realm-name="Secured by Elytron"/>
                </mechanism>
            </mechanism-configuration>
        </http-authentication-factory>
        <provider-http-server-mechanism-factory name="global"/>
    </http>
    <sasl>
        <sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="global" security-domain="ManagementDomain"/>
        <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="global" security-domain="ApplicationDomain"/>
        <provider-sasl-server-factory name="global"/>
    </sasl>
</subsystem>

On the other hand, the Undertow configuration will include the following application-security-domains definition:

<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" security-realm="ApplicationRealm" 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"/>
        </host>
    </server>
    <servlet-container name="default">
        <jsp-config/>
        <websockets/>
    </servlet-container>
    <handlers>
        <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
    </handlers>
    <filters>
        <response-header name="server-header" header-name="Server" header-value="WildFly/10"/>
        <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
    </filters>
    <application-security-domains>
        <application-security-domain name="other" http-authentication-factory="application-http-authentication"/>
        <application-security-domain name="web-security-domain" http-authentication-factory="http-db-auth"/>
    </application-security-domains>
</subsystem>

As we did for the previous example, include in your jboss-web.xml file a reference to the “web-security-domain” security domain:

<jboss-web>
   <security-domain>web-security</security-domain>
</jboss-web>
Found the article helpful? if so please follow us on Socials