An Elytron principal transformer can be used to map a principal from one form to another. Although there are a few different principal transformers that can be used out of the box with WildFly, it is also possible to implement custom principal transformers that can be registered using the Elytron subsystem. In this blog post, we’ll see how to create a custom principal transformer that can be used to convert usernames to all upper case characters. This can be useful if your identity store contains upper case usernames but you want to ignore the case when a username is being specified during the authentication process.
This blog post will make use of the custom-principal-transformer project in the elytron-examples repository:
Prerequisite configuration
Let’s first add a management user for the server - this is the user that we’re going to use later on when attempting to connect to the CLI. For this example, we’re going to create a filesystem-based identity store and add a user named “BOBSMITH” with password “bob123+” using the following CLI commands:
/subsystem=elytron/filesystem-realm=exampleRealm:add(path=fs-realm-users,relative-to=jboss.server.config.dir) /subsystem=elytron/filesystem-realm=exampleRealm:add-identity(identity=BOBSMITH) /subsystem=elytron/filesystem-realm=exampleRealm:set-password(identity=BOBSMITH,clear={password=bob123+}) /subsystem=elytron/filesystem-realm=exampleRealm:add-identity-attribute(identity=BOBSMITH,name=Roles,value=[SuperUser])
Next, we’re going to add the filesystem-realm that we just created to the “ManagementDomain” security domain that is already defined in the default Elytron subsystem configuration and we’re going to make this the default security realm for this security domain:
/subsystem=elytron/security-domain=ManagementDomain:list-add(name=realms, value={realm=exampleRealm}) /subsystem=elytron/security-domain=ManagementDomain:write-attribute(name=default-realm, value=exampleRealm)
Now, use the following commands to secure the management interface using Elytron:
/core-service=management/management-interface=http-interface:write-attribute(name=http-upgrade,value={enabled=true, sasl-authentication-factory=management-sasl-authentication}) /core-service=management/management-interface=http-interface:undefine-attribute(name=security-realm)
For this example, we’re also going to use RBAC to secure the management interface using our filesystem-based identity store. However, please note that this step is optional:
/core-service=management/access=authorization:write-attribute(name=provider, value=rbac) /core-service=management/access=authorization:write-attribute(name=use-identity-roles,value=true)
Finally, reload the server:
:reload
At this point, let’s try to connect to the CLI specifying “BobSmith” as the username:
$WILDFLY_HOME/bin/jboss-cli.sh -c --controller=remote+http://127.0.0.1:9990 --user=BobSmith --password=bob123+
Notice that authentication fails since the username in our identity store is “BOBSMITH” not “BobSmith”. In the next few sections, we’ll see how to create and make use of a custom principal transformer that can be used to convert the given principal name to all upper case characters.
Custom principal transformer implementation
To create a custom principal transformer, we need to create a class that implements the PrincipalTransformer interface. In particular, we need to provide an implementation for the apply method which will be used to map the given principal from one form to another. Our custom implementation, CasePrincipalTransformer, that converts the given principal name to all upper case characters can be found here.
Installing our custom principal transformer
Now that we’ve created our custom principal transformer, the next thing we need to do is install it in WildFly so we can make use of it in the Elytron subsystem. First, let’s build our custom-principal-transformer project:
mvn clean install
The above command produces a JAR that contains our custom implementation. Next, we can add a module that contains this JAR to WildFly using the CLI:
module add --name=org.wildfly.security.examples.custom-principal-transformer --resources=/PATH_TO_ELYTRON_EXAMPLES/elytron-examples/custom-principal-transformer/target/custom-principal-transformer-1.0.0.Alpha1-SNAPSHOT.jar --dependencies=org.wildfly.security.elytron,org.wildfly.extension.elytron
Finally, we can create a custom-principal-transformer in the Elytron subsystem that references both this new module and our custom principal transformer class that is contained in this module:
/subsystem=elytron/custom-principal-transformer=myPrincipalTransformer:add(module=org.wildfly.security.examples.custom-principal-transformer, class-name=org.wildfly.security.examples.CasePrincipalTransformer)
Making use of our custom principal transformer
We’re now ready to make use of our custom-principal-transformer. Let’s update our "ManagementDomain" to specify that our newly created custom-principal-transformer should be used as the pre-realm-principal-transformer - this is a principal transformer that gets applied before the realm is selected:
/subsystem=elytron/security-domain=ManagementDomain:write-attribute(name=pre-realm-principal-transformer,value=myPrincipalTransformer)
Next, reload the server using the :reload command.
Now, try connecting to the CLI again, specifying “BobSmith” as the username:
$WILDFLY_HOME/bin/jboss-cli.sh -c --controller=remote+http://127.0.0.1:9990 --user=BobSmith --password=bob123+
This time, authentication succeeds since our custom-principal-transformer gets used to convert the given username to all upper case characters, matching the username in our identity store.
Summary
This blog post has shown how to create and make use of a custom Elytron principal transformer.