Advanced EJB: Securing EJBs using a FileSystem realm and invoking them from a remote client using a credential store
The ejb-security quickstart demonstrates an advanced example on how to secure EJBs using a FileSystem realm with SCRAM-SHA-512 SASL authentication along with a client credential store. The focus is on the Elytron configuration, so if you wish to learn more about using Jakarta EE declarative security to control access to EJBs please refer to this blog.
An Overview of the FileSystem Realm
By default, when using the Elytron security subsystem, our application uses a properties file-based identity store. In this example, we wish to use a FileSystem realm which stores the identity information on a FileSystem by paging each identity in an XML along with its credentials and roles.
Configuring a FileSystem Realm
We start our configuration by connecting to the server using the following command:
$ WILDFLY_HOME/bin/jboss-cli.sh --connect
Note: Use of WILDFLY_HOME
In the following post, replace WILDFLY_HOME
with the actual path to your WildFly installation.
We then create a FileSystem realm under the Elytron subsystem by specifying a directory where to store these identities. Notice
in this case, we are storing the identities in a directory called fs-realm-users
relative to jboss.server.config.dir
:
/subsystem=elytron/filesystem-realm=fsRealm:add(path=fs-realm-users, relative-to=jboss.server.config.dir)
We can then add an identity, along with its password and role. For the implementation of this example, we need an identity
quickstartUser
, whose password is quickstartPwd1!
and whose Role is guest
:
/subsystem=elytron/filesystem-realm=fsRealm:add-identity(identity=quickstartUser)
/subsystem=elytron/filesystem-realm=fsRealm:set-password(clear={password=quickstartPwd1!}, identity=quickstartUser)
/subsystem=elytron/filesystem-realm=fsRealm:add-identity-attribute(identity=quickstartUser, name=Roles, value=[guest])
We then add a role decoder which will convert attributes from the identity provided by the security realm into roles:
/subsystem=elytron/simple-role-decoder=from-roles-attribute:add(attribute=Roles)
For more information about creating FileSystem realms along with all of its possible configurations, please refer to the Elytron documentation.
Configuring the Security Domain
We first configure an Elytron security domain called fsSD
to use the FileSystem realm and role decoder we specified
as follows:
/subsystem=elytron/security-domain=fsSD:add(realms=[{realm=fsRealm, role-decoder=from-roles-attribute}], default-realm=fsRealm,permission-mapper=default-permission-mapper)
Note that creating an additional security domain (fsSD
in this case) is not necessary. We could alternatively take the default ApplicationDomain
and add the
FileSystem realm, role-decoder and permission-mapper to it.
We configure a security domain other
in our EJB (as demonstrated by the @SecurityDomain
annotation). Since security for EJBs is handled by legacy security subsystems when deploying with WildFly,
we need to configure the security subsystem to be handled by Elytron by adding our security domain mapping in the
EJB subsystem as follows:
/subsystem=ejb3/application-security-domain=other:add(security-domain=fsSD)
Enabling SCRAM-SHA-512
Multiple authentication mechanisms can be configured for different protocols. Elytron provides support for two types of
authentication: HTTP authentication
and SASL authentication
. We want our SASL authentication factory to make
use of the FileSystem security domain we configured. Therefore, we add said security domain as follows:
/subsystem=elytron/sasl-authentication-factory=application-sasl-authentication:write-attribute(name=security-domain, value=fsSD)
By default, our authentication factory has enabled JBOSS-LOCAL-USER
and DIGEST-MD5
. Therefore, we enable SCRAM-SHA-512
as an additional SASL authentication mechanism by updating the
sasl-authentication-factory
as follows:
/subsystem=elytron/sasl-authentication-factory=application-sasl-authentication:list-add(name=mechanism-configurations, value={mechanism-name=SCRAM-SHA-512})
Finally, we update the http-remoting-connector to use our updated application-sasl-authentication-factory
as follows:
/subsystem=remoting/http-connector=http-remoting-connector:write-attribute(name=sasl-authentication-factory,value=application-sasl-authentication).
Configuring the Credential Store
For the purpose of this example, we aim to provide a more secure setup than specifying the client’s password in
clear-text in the wildfly-config.xml
file. As a result, we create a credential store locally as follows:
$ WILDFLY_HOME/bin/elytron-tool.sh credential-store --create --location "/PATH/TO/mycredstore.cs" --password StorePassword
Note this creates a credential store mycredstore.cs
locally with a corresponding password StorePassword
. We then
add an alias (quickstartUser
) storing the password (quickstartPwd1!
) to be used for the authentication configuration as follows:
$ WILDFLY_HOME/bin/elytron-tool.sh credential-store --location "/PATH/TO/mycredstore.cs" --password StorePassword --add quickstartUser --secret quickstartPwd1!
Configuring the Client (wildfly-config.xml)
Upon inspecting our wildfly-config.xml
, notice how the credential store to be used by the authentication client is
specified:
<credential-stores>
<credential-store name="mycredstore">
<attributes>
<attribute name="keyStoreType" value="JCEKS"/>
<attribute name="location" value="PATH/TO/mycredstore.cs"></attribute>
</attributes>
<protection-parameter-credentials>
<clear-password password="StorePassword"/>
</protection-parameter-credentials>
</credential-store>
</credential-stores>
Note you would need to replace "PATH/TO/mycredstore.cs"
with the actual path to your credential store.
Then, notice the reference to our credential store along with the alias to extract the password from, and the
specification of the desired authentication mechanism under the <authentication-configurations>
tag:
<authentication-configurations>
<configuration name="default-config">
<set-user-name name="quickstartUser"/>
<credentials>
<credential-store-reference store="mycredstore" alias="quickstartUser"/>
</credentials>
<sasl-mechanism-selector selector="SCRAM-SHA-512"/>
<providers>
<use-service-loader />
</providers>
</configuration>
</authentication-configurations>
Also, note the <providers>
tag which will result in the Elytron providers being registered.