[[Using_the_Elytron_Subsystem]]
= Using the Elytron Subsystem

[[set-up-and-configure-authentication-for-applications]]
== Set Up and Configure Authentication for Applications

[[configure-authentication-with-a-properties-file-based-identity-store]]
=== Configure Authentication with a Properties File-Based Identity Store

[[create-properties-files]]
==== Create properties files:

You need to create two properties files: one that maps user to passwords
and another that maps users to roles. Usually these files are located in
the _jboss.server.config.dir_ directory and follow the naming convention
_*-users.properties_ and _*-roles.properties_, but other locations and
names may be used. The _*-users.properties_ file must also contain a
reference to the _properties-realm_, which you will create in the next
step: _#$REALM_NAME=YOUR_PROPERTIES_REALM_NAME$_

*Example user to password file: example-users.properties*

....
#$REALM_NAME=examplePropRealm$
user1=password123
user2=password123
....

*Example user to roles file: example-roles.properties*

....
user1=Admin
user2=Guest
....

[[configure-a-properties-realm-in-wildfly]]
==== Configure a properties-realm in WildFly:

[source,options="nowrap"]
----
/subsystem=elytron/properties-realm=examplePropRealm:add(groups-attribute=groups,groups-properties={path=example-roles.properties,relative-to=jboss.server.config.dir},users-properties={path=example-users.properties,relative-to=jboss.server.config.dir,plain-text=true})
----

The name of the _properties-realm_ is _examplePropRealm_, which is used
in the previous step in the _example-users.properties_ file. Also, if
your properties files are located outside of _jboss.server.config.dir_,
then you need to change the _path_ and _relative-to_ values
appropriately.

[[configure-a-security-domain]]
==== Configure a security-domain:

[source,options="nowrap"]
----
/subsystem=elytron/security-domain=exampleSD:add(realms=[{realm=examplePropRealm,role-decoder=groups-to-roles}],default-realm=examplePropRealm,permission-mapper=default-permission-mapper)
----

[[configure-an-http-authentication-factory]]
==== Configure an http-authentication-factory:

[source,options="nowrap"]
----
/subsystem=elytron/http-authentication-factory=example-http-auth:add(http-server-mechanism-factory=global,security-domain=exampleSD,mechanism-configurations=[{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=exampleApplicationDomain}]}])
----

This example shows creating an _http-authentication-factory_ using
_BASIC_ authentication, but it could be updated to other mechanisms such
as _FORM_.

[[configure-an-application-security-domain-in-the-undertow-subsystem]]
==== Configure an application-security-domain in the Undertow subsystem:

[source,options="nowrap"]
----
/subsystem=undertow/application-security-domain=exampleApplicationDomain:add(http-authentication-factory=example-http-auth)
----

[[configure-your-applications-web.xml-and-jboss-web.xml.]]
==== Configure your application's web.xml and jboss-web.xml.

Your application's _web.xml_ and _jboss-web.xml_ must be updated to use
the _application-security-domain_ you configured in WildFly. An example
of this is available in the
<<configure-applications-to-use-elytron-or-legacy-security-for-authentication,Configure
Applications to Use Elytron or Legacy Security for Authentication>>
section.

[[configure-authentication-with-a-filesystem-based-identity-store]]
=== Configure Authentication with a Filesystem-Based Identity Store

[[chose-a-directory-for-users]]
==== Chose a directory for users:

You need a directory where your users will be stored. In this example,
we are using a directory called _fs-realm-users_ located in
_jboss.server.config.dir_.

[[configure-a-filesystem-realm-in-wildfly]]
==== Configure a filesystem-realm in WildFly:

[source,options="nowrap"]
----
/subsystem=elytron/filesystem-realm=exampleFsRealm:add(path=fs-realm-users,relative-to=jboss.server.config.dir)
----

If your directory is located outside of _jboss.server.config.dir_, then
you need to change the _path_ and _relative-to_ values appropriately.

[[add-a-user]]
==== Add a user:

When using the _filesystem-realm_, you can add users using the
management CLI.

[source,options="nowrap"]
----
/subsystem=elytron/filesystem-realm=exampleFsRealm:add-identity(identity=user1)
/subsystem=elytron/filesystem-realm=exampleFsRealm:set-password(clear={password="password123"}, identity=user1)
/subsystem=elytron/filesystem-realm=exampleFsRealm:add-identity-attribute(identity=user1, name=Roles, value=["Admin","Guest"])
----

[[add-a-simple-role-decoder]]
==== Add a simple-role-decoder:

[source,options="nowrap"]
----
/subsystem=elytron/simple-role-decoder=from-roles-attribute:add(attribute=Roles)
----

This _simple-role-decoder_ decodes a principal's roles from the _Roles_
attribute. You can change this value if your roles are in a different
attribute.

[[configure-a-security-domain-1]]
==== Configure a security-domain:

[source,options="nowrap"]
----
/subsystem=elytron/security-domain=exampleFsSD:add(realms=[{realm=exampleFsRealm,role-decoder=from-roles-attribute}],default-realm=exampleFsRealm,permission-mapper=default-permission-mapper)
----

[[configure-an-http-authentication-factory-1]]
==== Configure an http-authentication-factory:

[source,options="nowrap"]
----
/subsystem=elytron/http-authentication-factory=example-fs-http-auth:add(http-server-mechanism-factory=global,security-domain=exampleFsSD,mechanism-configurations=[{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=exampleApplicationDomain}]}])
----

This example shows creating an _http-authentication-factory_ using
_BASIC_ authentication, but it could be updated to other mechanisms such
as _FORM_.

[[configure-an-application-security-domain-in-the-undertow-subsystem-1]]
==== Configure an application-security-domain in the Undertow subsystem:

[source,options="nowrap"]
----
/subsystem=undertow/application-security-domain=exampleApplicationDomain:add(http-authentication-factory=example-fs-http-auth)
----

[[configure-your-applications-web.xml-and-jboss-web.xml.-1]]
==== Configure your application's web.xml and jboss-web.xml.

Your application's _web.xml_ and _jboss-web.xml_ must be updated to use
the _application-security-domain_ you configured in WildFly. An example
of this is available in the
<<configure-applications-to-use-elytron-or-legacy-security-for-authentication,Configure
Applications to Use Elytron or Legacy Security for Authentication>>
section.

Your application is now using a filesystem-based identity store for
authentication.

[[configure-authentication-with-a-database-identity-store]]
=== Configure Authentication with a Database Identity Store

[[determine-your-database-format-for-usernames-passwords-and-roles]]
==== Determine your database format for usernames, passwords, and roles:

To set up authentication using a database for an identity store, you
need to determine how your usernames, passwords, and roles are stored in
that database. In this example, we are using a single table with the
following sample data:

[cols=",,",options="header"]
|=========================
|username |password |roles
|user1 |password123 |Admin
|user2 |password123 |Guest
|=========================

[[configure-a-datasource]]
==== Configure a datasource:

To connect to a database from WildFly, you must have the appropriate
database driver deployed as well as a datasource configured. This
example shows deploying the driver for postgres and configuring a
datasource in WildFly:

[source,options="nowrap"]
----
deploy /path/to/postgresql-9.4.1210.jar
 
data-source add --name=examplePostgresDS --jndi-name=java:jboss/examplePostgresDS --driver-name=postgresql-9.4.1210.jar  --connection-url=jdbc:postgresql://localhost:5432/postgresdb --user-name=postgresAdmin --password=mysecretpassword
----

[[configure-a-jdbc-realm-in-wildfly]]
==== Configure a jdbc-realm in WildFly:

[source,options="nowrap"]
----
/subsystem=elytron/jdbc-realm=exampleDbRealm:add(principal-query=[{sql="SELECT password,roles FROM wildfly_users WHERE username=?",data-source=examplePostgresDS,clear-password-mapper={password-index=1},attribute-mapping=[{index=2,to=groups}]}])
----

*NOTE:* The above example shows how to obtain passwords and roles from a
single _principal-query_. You can also create additional
_principal-query_ with _attribute-mapping_ attributes if you require
multiple queries to obtain roles or additional authentication or
authorization information.

[[configure-a-security-domain-2]]
==== Configure a security-domain:

[source,options="nowrap"]
----
/subsystem=elytron/security-domain=exampleDbSD:add(realms=[{realm=exampleDbRealm,role-decoder=groups-to-roles}],default-realm=exampleDbRealm,permission-mapper=default-permission-mapper)
----

[[configure-an-http-authentication-factory-2]]
==== Configure an http-authentication-factory:

[source,options="nowrap"]
----
/subsystem=elytron/http-authentication-factory=example-db-http-auth:add(http-server-mechanism-factory=global,security-domain=exampleDbSD,mechanism-configurations=[{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=exampleDbSD}]}])
----

This example shows creating an _http-authentication-factory_ using
_BASIC_ authentication, but it could be updated to other mechanisms such
as _FORM_.

[[configure-an-application-security-domain-in-the-undertow-subsystem-2]]
==== Configure an application-security-domain in the Undertow subsystem:

[source,options="nowrap"]
----
/subsystem=undertow/application-security-domain=exampleApplicationDomain:add(http-authentication-factory=example-db-http-auth)
----

[[configure-your-applications-web.xml-and-jboss-web.xml.-2]]
==== Configure your application's web.xml and jboss-web.xml.

Your application's _web.xml_ and _jboss-web.xml_ must be updated to use
the _application-security-domain_ you configured in WildFly. An example
of this is available in the
<<configure-applications-to-use-elytron-or-legacy-security-for-authentication,Configure
Applications to Use Elytron or Legacy Security for Authentication>>
section.

[[configure-authentication-with-an-ldap-based-identity-store]]
=== Configure Authentication with an LDAP-Based Identity Store

[[determine-your-ldap-format-for-usernames-passwords-and-roles]]
==== Determine your LDAP format for usernames, passwords, and roles:

To set up authentication using an LDAP server for an identity store, you
need to determine how your usernames, passwords, and roles are stored.
In this example, we are using the following structure:

[source,java,options="nowrap"]
----
dn: dc=wildfly,dc=org
dc: wildfly
objectClass: top
objectClass: domain
 
dn: ou=Users,dc=wildfly,dc=org
objectClass: organizationalUnit
objectClass: top
ou: Users
 
dn: uid=jsmith,ou=Users,dc=wildfly,dc=org
objectClass: top
objectClass: person
objectClass: inetOrgPerson
cn: John Smith
sn: smith
uid: jsmith
userPassword: password123
 
dn: ou=Roles,dc=wildfly,dc=org
objectclass: top
objectclass: organizationalUnit
ou: Roles
 
dn: cn=Admin,ou=Roles,dc=wildfly,dc=org
objectClass: top
objectClass: groupOfNames
cn: Admin
member: uid=jsmith,ou=Users,dc=wildfly,dc=org
----

[[configure-a-dir-context]]
==== Configure a dir-context:

To connect to the LDAP server from WildFly, you need to configure a
_dir-context_ that provides the URL as well as the principal used to
connect to the server.

[source,options="nowrap"]
----
/subsystem=elytron/dir-context=exampleDC:add(url="ldap://127.0.0.1:10389",principal="uid=admin,ou=system",credential-reference={clear-text="secret"})
----

[[configure-an-ldap-realm-in-wildfly]]
==== Configure an ldap-realm in WildFly:

[source,options="nowrap"]
----
/subsystem=elytron/ldap-realm=exampleLR:add(dir-context=exampleDC,identity-mapping={search-base-dn="ou=Users,dc=wildfly,dc=org",rdn-identifier="uid",user-password-mapper={from="userPassword"},attribute-mapping=[{filter-base-dn="ou=Roles,dc=wildfly,dc=org",filter="(&(objectClass=groupOfNames)(member={1}))",from="cn",to="Roles"}]})
----

[[add-a-simple-role-decoder-1]]
==== Add a simple-role-decoder:

[source,options="nowrap"]
----
/subsystem=elytron/simple-role-decoder=from-roles-attribute:add(attribute=Roles)
----

[[configure-a-security-domain-3]]
==== Configure a security-domain:

[source,options="nowrap"]
----
/subsystem=elytron/security-domain=exampleLdapSD:add(realms=[{realm=exampleLR,role-decoder=from-roles-attribute}],default-realm=exampleLR,permission-mapper=default-permission-mapper)
----

[[configure-an-http-authentication-factory-3]]
==== Configure an http-authentication-factory:

[source,options="nowrap"]
----
/subsystem=elytron/http-authentication-factory=example-ldap-http-auth:add(http-server-mechanism-factory=global,security-domain=exampleLdapSD,mechanism-configurations=[{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=exampleApplicationDomain}]}])
----

This example shows creating an _http-authentication-factory_ using
_BASIC_ authentication, but it could be updated to other mechanisms such
as _FORM_.

[[configure-an-application-security-domain-in-the-undertow-subsystem-3]]
==== Configure an application-security-domain in the Undertow subsystem:

[source,options="nowrap"]
----
/subsystem=undertow/application-security-domain=exampleApplicationDomain:add(http-authentication-factory=example-ldap-http-auth)
----

[[configure-your-applications-web.xml-and-jboss-web.xml.-3]]
==== Configure your application's web.xml and jboss-web.xml.

Your application's _web.xml_ and _jboss-web.xml_ must be updated to use
the _application-security-domain_ you configured in WildFly. An example
of this is available in the
<<configure-applications-to-use-elytron-or-legacy-security-for-authentication,Configure
Applications to Use Elytron or Legacy Security for Authentication>>
section.

*IMPORTANT:* In cases where you configure an LDAP server in the
_elytron_ subsystem for authentication and that LDAP server then becomes
unreachable, WildFly will return a _500_, or internal server error,
error code when attempting authentication using that unreachable LDAP
server. This behavior differs from the legacy _security_ subsystem,
which will return a _401_, or unauthorized, error code under the same
conditions.

[[configure-authentication-with-certificates]]
=== Configure Authentication with Certificates

*IMPORTANT:* Before you can set up certificate-based authentication, you
must have two-way SSL configured.

[[configure-a-key-store-realm.]]
==== Configure a key-store-realm.

[source,options="nowrap"]
----
/subsystem=elytron/key-store-realm=ksRealm:add(key-store=twoWayTS)
----

You must configure this realm with a truststore that contains the
client's certificate. The authentication process uses the same
certificate presented by the client during the two-way SSL handshake.

[[create-a-decoder.]]
==== Create a Decoder.

You need to create a _x500-attribute-principal-decoder_ to decode the
principal you get from your certificate. The below example will decode
the principal based on the first _CN_ value.

[source,options="nowrap"]
----
/subsystem=elytron/x500-attribute-principal-decoder=CNDecoder:add(oid="2.5.4.3",maximum-segments=1)
----

For example, if the full _DN_ was
_CN=client,CN=client-certificate,DC=example,DC=jboss,DC=org_,
_CNDecoder_ would decode the principal as _client_. This decoded
principal is used as the _alias_ value to lookup a certificate in the
truststore configured in _ksRealm_.

*IMPORTANT:* The decoded principal * *MUST** must be the _alias_ value
you set in your server's truststore for the client's certificate.

[[configure-an-evidence-decoder.]]
==== Configure an evidence-decoder

By default, the principal associated with a certificate will be the subject name
from the certificate. This subject name will then be rewritten using any configured
principal decoders and principal transformers to obtain the name that should be used
when locating and loading the identity from the underlying identity store.

To specify that a subject alternative name from a certificate should be used as the
principal associated with that certificate, an `x509-subject-alt-name-evidence-decoder`
needs to be configured. This element has two attributes:

** `alt-name-type` - The subject alternative name type to decode. This attribute is
required. Must be one of the subject alternative name types that can be represented
as a `String`:
*** `rfc822Name`
*** `dNSName`
*** `uniformResourceIdentifier`
*** `iPAddress`
*** `registeredID`
*** `directoryName`

** `segment` - The 0-based occurrence of the subject alternative name to map. This
attribute is optional and only used when there is more than one subject alternative
name of the given `alt-name-type`. The default value is `0`.

For example, consider the following X.509 v3 Subject Alternative Name extension from
the first certificate in an X.509 certificate chain:

[source,xml]
----
X509v3 Subject Alternative Name:
DNS:one.example.org, IP Address:127.0.0.1
----

To associate the certificate chain evidence with the principal "one.example.org", the
following `x509-subject-alt-name-evidence-decoder` could be configured:

[source,options="nowrap"]
----
/subsystem=elytron/x509-subject-alt-name-evidence-decoder=exampleDnsDecoder:add(alt-name-type=dNSName)
----

Next, consider the following X.509 v3 Subject Alternative Name extension from the first
certificate in an X.509 certificate chain:

[source,xml]
----
X509v3 Subject Alternative Name:
DNS:one.example.org, DNS:two.example.org, IP Address:127.0.0.1
----

To associate the evidence with the principal "two.example.org", the following
`x509-subject-alt-name-evidence-decoder` could be configured:

[source,options="nowrap"]
----
/subsystem=elytron/x509-subject-alt-name-evidence-decoder=anotherDnsDecoder:add(alt-name-type=dNSName, segment=1)
----

It is also possible to configure an `x500-subject-evidence-decoder`. This evidence decoder
will extract the subject from the first certificate in the certificate chain, as an `X500Principal`.
Example configuration:

[source,options="nowrap"]
----
/subsystem=elytron/x500-subject-evidence-decoder=exampleSubjectDecoder:add()
----

To make use of a custom `org.wildfly.security.auth.server.EvidenceDecoder` implementation, a
`custom-evidence-decoder` can be configured. The custom implementation class needs to first be
packaged in a JAR. A module can then be added to WildFly that contains this JAR. See
<<Custom_Components#, Custom Components>> for more information on how to add a custom Elytron
component to WildFly.

Example configuration:

[source,options="nowrap"]
----
/subsystem=elytron/custom-evidence-decoder=myCustomEvidenceDecoder:add(module=org.wildfly.security.examples, class-name=org.wildfly.security.examples.MyCustomEvidenceDecoder)
----

Finally, it is also possible to configure an `aggregate-evidence-decoder`. This consists of
two or more `evidence-decoder` elements where each element is reference to a configured
evidence decoder. Given evidence, these evidence decoders will be attempted in order until
one returns a non-null principal or until there are no more evidence decoders left to try.

Example configuration:

[source,options="nowrap"]
----
/subsystem=elytron/x509-subject-alt-name-evidence-decoder=emailDecoder:add(alt-name-type=rfc822Name)
/subsystem=elytron/x509-subject-alt-name-evidence-decoder=dnsDecoder:add(alt-name-type=dNSName)
/subsystem=elytron/x500-subject-evidence-decoder=subjectDecoder:add()
/subsystem=elytron/aggregate-evidence-decoder=aggregateDecoder:add(evidence-decoders=[emailDecoder,subjectDecoder,dnsDecoder])
----

Once an `evidence-decoder` has been configured, it can be referenced from a `security-domain`:

[source,options="nowrap"]
----
/subsystem=elytron/security-domain=exampleCertSD:add(..., evidence-decoder=aggregateDecoder)
----

If no `evidence-decoder` is specified for a `security-domain`, then the principal associated with the evidence will
just be the default principal for the evidence type, i.e., for an X.509 certificate chain, this would continue to
default to the subject from the first certificate in the certificate chain.

[[add-a-constant-role-mapper-for-assigning-roles.]]
==== Add a constant-role-mapper for assigning roles.

This is example uses a _constant-role-mapper_ to assign roles to a
principal from _ksRealm_ but other approaches may also be used.

[source,options="nowrap"]
----
/subsystem=elytron/constant-role-mapper=constantClientCertRole:add(roles=[Admin,Guest])
----

[[configure-a-security-domain.]]
==== Configure a security-domain.

[source,options="nowrap"]
----
/subsystem=elytron/security-domain=exampleCertSD:add(realms=[{realm=ksRealm}],default-realm=ksRealm,permission-mapper=default-permission-mapper,principal-decoder=CNDecoder,role-mapper=constantClientCertRole)
----

[[configure-an-http-authentication-factory.]]
==== Configure an http-authentication-factory.

[source,options="nowrap"]
----
/subsystem=elytron/http-authentication-factory=exampleCertHttpAuth:add(http-server-mechanism-factory=global,security-domain=exampleCertSD,mechanism-configurations=[{mechanism-name=CLIENT_CERT,mechanism-realm-configurations=[{realm-name=exampleApplicationDomain}]}])
----

[[configure-an-application-security-domain-in-the-undertow-subsystem.]]
==== Configure an application-security-domain in the Undertow subsystem.

[source,options="nowrap"]
----
/subsystem=undertow/application-security-domain=exampleApplicationDomain:add(http-authentication-factory=exampleCertHttpAuth)
----

[[update-server-ssl-context.]]
==== Update server-ssl-context.

[source,options="nowrap"]
----
/subsystem=elytron/server-ssl-context=twoWaySSC:write-attribute(name=security-domain,value=exampleCertSD)
/subsystem=elytron/server-ssl-context=twoWaySSC:write-attribute(name=authentication-optional, value=true)
----

[[configure-your-applications-web.xml-and-jboss-web.xml.-4]]
==== Configure your application's web.xml and jboss-web.xml.

Your application's _web.xml_ and _jboss-web.xml_ must be updated to use
the _application-security-domain_ you configured in WildFly. An example
of this is available in the
<<configure-applications-to-use-elytron-or-legacy-security-for-authentication,Configure
Applications to Use Elytron or Legacy Security for Authentication>>
section.

In addition, you need to update your _web.xml_ to use _CLIENT-CERT_ as
its authentication method.

[source,xml,options="nowrap"]
----
<login-config>
  <auth-method>CLIENT-CERT</auth-method>
  <realm-name>exampleApplicationDomain</realm-name>
</login-config>
----

[[configure-authentication-with-a-kerberos-based-identity-store]]
=== Configure Authentication with a Kerberos-Based Identity Store

*IMPORTANT*: The following steps assume you have a working KDC and
Kerberos domain as well as your client browsers configured.

[[configure-a-kerberos-security-factory.]]
==== Configure a kerberos-security-factory.

[source,options="nowrap"]
----
/subsystem=elytron/kerberos-security-factory=krbSF:add(principal="HTTP/host@REALM",path="/path/to/http.keytab",mechanism-oids=[1.2.840.113554.1.2.2,1.3.6.1.5.5.2])
----

[[configure-the-system-properties-for-kerberos.]]
==== Configure the system properties for Kerberos.

Depending on how your environment is configured, you will need to set
some of the system properties below.

[cols=",",options="header"]
|======================================================================
|System Property |Description
|java.security.krb5.kdc |The host name of the KDC.
|java.security.krb5.realm |The name of the realm.
|java.security.krb5.conf |The path to the configuration krb5.conf file.
|sun.security.krb5.debug |If true, debugging mode will be enabled.
|======================================================================

To configure a system property in WildFly:

[source,java,options="nowrap"]
----
/system-property=java.security.krb5.conf:add(value="/path/to/krb5.conf")
----

[[configure-an-eltyron-security-realm-for-assigning-roles.]]
==== Configure an Elytron security realm for assigning roles.

The the client's Kerberos token will provide the principal, but you need
a way to map that principal to a role for your application. There are
several ways to accomplish this, but this example creates a
_filesystem-realm_, adds a user to the realm that matches the principal
from the Kerberos token, and assigns roles to that user.

[source,options="nowrap"]
----
/subsystem=elytron/filesystem-realm=exampleFsRealm:add(path=fs-realm-users,relative-to=jboss.server.config.dir)
/subsystem=elytron/filesystem-realm=exampleFsRealm:add-identity(identity=user1@REALM)
/subsystem=elytron/filesystem-realm=exampleFsRealm:add-identity-attribute(identity=user1@REALM,name=Roles,value=["Admin","Guest"])
----

[[add-a-simple-role-decoder.]]
==== Add a simple-role-decoder.

[source,options="nowrap"]
----
/subsystem=elytron/simple-role-decoder=from-roles-attribute:add(attribute=Roles)
----

This _simple-role-decoder_ decodes a principal's roles from the _Roles_
attribute. You can change this value if your roles are in a different
attribute.

[[configure-a-security-domain.-1]]
==== Configure a security-domain.

[source,options="nowrap"]
----
/subsystem=elytron/security-domain=exampleFsSD:add(realms=[{realm=exampleFsRealm,role-decoder=from-roles-attribute}],default-realm=exampleFsRealm,permission-mapper=default-permission-mapper)
----

[[configure-an-http-authentication-factory-that-uses-the-kerberos-security-factory.]]
==== Configure an http-authentication-factory that uses the
kerberos-security-factory.

[source,options="nowrap"]
----
/subsystem=elytron/http-authentication-factory=example-krb-http-auth:add(http-server-mechanism-factory=global,security-domain=exampleFsSD,mechanism-configurations=[{mechanism-name=SPNEGO,mechanism-realm-configurations=[{realm-name=exampleFsSD}],credential-security-factory=krbSF}])
----

[[configure-an-application-security-domain-in-the-undertow-subsystem-4]]
==== Configure an application-security-domain in the Undertow subsystem:

[source,options="nowrap"]
----
/subsystem=undertow/application-security-domain=exampleApplicationDomain:add(http-authentication-factory=example-krb-http-auth)
----

[[configure-your-applications-web.xml-jboss-web.xml-and-jboss-deployment-structure.xml.]]
==== Configure your application's web.xml, jboss-web.xml and
jboss-deployment-structure.xml.

Your application's _web.xml_ and _jboss-web.xml_ must be updated to use
the _application-security-domain_ you configured in WildFly. An example
of this is available in the
<<configure-applications-to-use-elytron-or-legacy-security-for-authentication,Configure
Applications to Use Elytron or Legacy Security for Authentication>>
section.

In addition, you need to update your _web.xml_ to use _SPNEGO_ as its
authentication method.

[source,xml,options="nowrap"]
----
<login-config>
  <auth-method>SPNEGO</auth-method>
  <realm-name>exampleApplicationDomain</realm-name>
</login-config>
----

[[configure-authentication-with-a-form-as-a-fallback-for-kerberos]]
=== Configure Authentication with a Form as a Fallback for Kerberos

[[configure-kerberos-based-authentication.]]
==== Configure kerberos-based authentication.

Configuring kerberos-based authentication is covered in a previous
section.

[[add-a-mechanism-for-form-authentication-in-the-http-authentication-factory.]]
==== Add a mechanism for FORM authentication in the
http-authentication-factory.

You can use the existing _http-authentication-factory_ you configured
for kerberos-based authentication and and an additional mechanism for
_FORM_ authentication.

[source,options="nowrap"]
----
/subsystem=elytron/http-authentication-factory=example-krb-http-auth:list-add(name=mechanism-configurations, value={mechanism-name=FORM})
----

[[add-additional-fallback-principals.]]
==== Add additional fallback principals.

The existing configuration for kerberos-based authentication should
already have a security realm configured for mapping principals from
kerberos token to roles for the application. You can add additional
users for fallback authentication to that realm. For example if you used
a _filesystem-realm_, you can simply create a new user with the
appropriate roles:

[source,options="nowrap"]
----
/subsystem=elytron/filesystem-realm=exampleFsRealm:add-identity(identity=fallbackUser1)
/subsystem=elytron/filesystem-realm=exampleFsRealm:set-password(identity=fallbackUser1,clear={password="password123"})
/subsystem=elytron/filesystem-realm=exampleFsRealm:add-identity-attribute(identity=fallbackUser1,name=Roles,value=["Admin","Guest"])
----

[[update-the-web.xml-for-form-fallback.]]
==== Update the web.xml for FORM fallback.

You need to update the _web.xml_ to use the value _SPNEGO,FORM_ for the
_auth-method_, which will use _FORM_ as a fallback authentication method
if _SPNEGO_ fails. You also need to specify the location of your login
and error pages.

[source,xml,options="nowrap"]
----
<login-config>
  <auth-method>SPNEGO,FORM</auth-method>
  <realm-name>exampleApplicationDomain</realm-name>
  <form-login-config>
    <form-login-page>/login.jsp</form-login-page>
    <form-error-page>/error.jsp</form-error-page>
  </form-login-config>
</login-config>
----

[[configure-applications-to-use-elytron-or-legacy-security-for-authentication]]
=== Configure Applications to Use Elytron or Legacy Security for
Authentication

After you have configured the _elytron_ or legacy _security_ subsystems
for authentication, you need to configure your application to use it.

[[configure-your-applications-web.xml.]]
==== Configure your application's web.xml.

Your application's _web.xml_ needs to be configured to use the
appropriate authentication method. When using _elytron_, this is defined
in the _http-authentication-factory_ you created. When using the legacy
_security_ subsystem, this depends on your login module and the type of
authentication you want to configure.

Example _web.xml_ with _BASIC_ Authentication

[source,xml,options="nowrap"]
----
<web-app>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>secure</web-resource-name>
      <url-pattern>/secure/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>Admin</role-name>
    </auth-constraint>
  </security-constraint>
  <security-role>
    <description>The role that is required to log in to /secure/*</description>
    <role-name>Admin</role-name>
  </security-role>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>exampleApplicationDomain</realm-name>
  </login-config>
</web-app>
----

_BASIC_ Authentication can be configured to be silent
[source, xml]
----
<auth-method>BASIC?silent=true</auth-method>
----
Basic authentication in silent mode will send challenge to authenticate only if the request
contained authorization header, otherwise it is assumed another method will send the challenge.

[[configure-your-application-to-use-a-security-domain.]]
==== Configure your application to use a security domain.

You can configure your application's _jboss-web.xml_ to specify the
security domain you want to use for authentication. When using the
_elytron_ subsystem, this is defined when you created the
_application-security-domain_. When using the legacy _security_
subsystem, this is the name of the legacy security domain.

Example _jboss-web.xml_

[source,xml,options="nowrap"]
----
<jboss-web>
  <security-domain>exampleApplicationDomain</security-domain>
</jboss-web>
----

Using _jboss-web.xml_ allows you to configure the security domain for a
single application only. Alternatively, you can specify a default
security domain for all applications using the _undertow_ subsystem.
This allows you to omit using _jboss-web.xml_ to configure a security
domain for an individual application.

[source,options="nowrap"]
----
/subsystem=undertow:write-attribute(name=default-security-domain, value="exampleApplicationDomain")
----

*IMPORTANT*: Setting _default-security-domain_ in the _undertow_
subsystem will apply to *ALL* applications. If _default-security-domain_
is set and an application specifies a security domain in a
_jboss-web.xml_ file, the configuration in _jboss-web.xml_ will override
the _default-security-domain_ in the _undertow_ subsystem.

[[using-elytron-and-legacy-security-subsystems-in-parallel]]
==== Using Elytron and Legacy Security Subsystems in Parallel

You can define authentication in both the _elytron_ and legacy
_security_ subsystems and use them in parallel. If you use both
_jboss-web.xml_ and _default-security-domain_ in the _undertow_
subsystem, WildFly will first try to match the configured security
domain in the _elytron_ subsystem. If a match is not found, then WildFly
will attempt to match the security domain with one configured in the
legacy _security_ subsystem. If the _elytron_ and legacy _security_
subsystem each have a security domain with the same name, the _elytron_
security domain is used.

[[override-an-applications-authentication-configuration]]
=== Override an Application's Authentication Configuration

You can override the authentication configuration of an application with
one configured in WildFly. To do this, use the
_override-deployment-configuration_ property in the
_application-security-domain_ section of the _undertow_ subsystem:

[source,options="nowrap"]
----
/subsystem=undertow/application-security-domain=exampleApplicationDomain:write-attribute(name=override-deployment-config,value=true)
----

For example, an application is configured to use _FORM_ authentication
with the _exampleApplicationDomain_ in its _jboss-web.xml_.

_Example jboss-web.xml_

[source,xml,options="nowrap"]
----
<login-config>
  <auth-method>FORM</auth-method>
  <realm-name>exampleApplicationDomain</realm-name>
</login-config>
----

By enabling _override-deployment-configuration_, you can create a new
_http-authentication-factory_ that specifies a different authentication
mechanism such as _BASIC_.

_Example http-authentication-factory_

[source,options="nowrap"]
----
/subsystem=elytron/http-authentication-factory=exampleHttpAuth:read-resource()
{
    "outcome" => "success",
    "result" => {
        "http-server-mechanism-factory" => "global",
        "mechanism-configurations" => [{
            "mechanism-name" => "BASIC",
            "mechanism-realm-configurations" => [{"realm-name" => "exampleApplicationDomain"}]
        }],
        "security-domain" => "exampleSD"
    }
}
----

This will override the authentication mechanism defined in the
application's _jboss-web.xml_ and attempt to authenticate a user using
_BASIC_ instead of _FORM_.

[[create-and-use-a-credential-store]]
=== Create and Use a Credential Store

[[create-credential-store.]]
==== Create credential store.

[source,options="nowrap"]
----
/subsystem=elytron/credential-store=exampleCS:add(relative-to=jboss.server.data.dir, location=example.jceks,create=true,credential-reference={clear-text=cs-secret})
----

[[add-a-credential-to-a-credential-store.]]
==== Add a credential to a credential store.

[source,options="nowrap"]
----
/subsystem=elytron/credential-store=exampleCS:add-alias(alias=keystorepw,secret-value=secret)
----

[[list-all-credentials-in-a-credential-store.]]
==== List all credentials in a credential store.

[source,options="nowrap"]
----
/subsystem=elytron/credential-store=exampleCS:read-aliases()
{
    "outcome" => "success",
    "result" => ["keystorepw"]
}
----

[[remove-a-credential-from-a-credential-store.]]
==== Remove a credential from a credential store.

[source,options="nowrap"]
----
/subsystem=elytron/credential-store=exampleCS:remove-alias(alias=keystorepw)
----

[[use-a-credential-store.]]
==== Use a credential store.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=twoWayKS:write-attribute(name=credential-reference,value={store=exampleCS,alias=keystorepw})
----

[[set-up-and-configure-authentication-for-the-management-interfaces]]
== Set up and Configure Authentication for the Management Interfaces

[[secure-the-management-interfaces-with-a-new-identity-store]]
=== Secure the Management Interfaces with a New Identity Store

[[create-a-security-domain-and-any-supporting-security-realms-decoders-or-mappers-for-your-identity-store.]]
==== Create a security domain and any supporting security realms,
decoders, or mappers for your identity store.

This process is covered in a previous section. For example, if you
wanted to secure the management interfaces using a filesystem-based
identity store, you would follow the steps in
<<configure-authentication-with-a-filesystem-based-identity-store,Configure
Authentication with a Filesystem-Based Identity Store>>.

[[create-an-http-authentication-factory-or-sasl-authentication-factory.]]
==== Create an http-authentication-factory or
sasl-authentication-factory.

Example _http-authentication-factory_

[source,options="nowrap"]
----
/subsystem=elytron/http-authentication-factory=example-http-auth:add(http-server-mechanism-factory=global,security-domain=exampleSD,mechanism-configurations=[{mechanism-name=DIGEST,mechanism-realm-configurations=[{realm-name=exampleManagementRealm}]}])
----

Example _sasl-authentication-factory_

[source,options="nowrap"]
----
/subsystem=elytron/sasl-authentication-factory=example-sasl-auth:add(sasl-server-factory=configured,security-domain=exampleSD,mechanism-configurations=[{mechanism-name=DIGEST-MD5,mechanism-realm-configurations=[{realm-name=exampleManagementRealm}]}])
----

[[update-the-management-interfaces-to-use-your-http-authentication-factory-or-sasl-authentication-factory.]]
==== Update the management interfaces to use your
http-authentication-factory or sasl-authentication-factory.

Example update _http-authentication-factory_

[source,options="nowrap"]
----
/core-service=management/management-interface=http-interface:write-attribute(name=http-authentication-factory, value=example-http-auth)
{
   "outcome" => "success",
   "response-headers" => {
       "operation-requires-reload" => true,
       "process-state" => "reload-required"
   }
}
 
reload
----

Example update _sasl-authentication-factory_

[source,options="nowrap"]
----
/core-service=management/management-interface=http-interface:write-attribute(name=http-upgrade.sasl-authentication-factory, value=example-sasl-auth)
{
   "outcome" => "success",
   "response-headers" => {
       "operation-requires-reload" => true,
       "process-state" => "reload-required"
   }
}
 
reload
----

[[silent-authentication]]
=== Silent Authentication

By default, WildFly provides an authentication mechanism for local
users, also know as silent authentication, through the _local_ security
realm.

Silent authentication must be used via a _sasl-authentication-factory_.

*IMPORTANT*: When enabling silent authentication, you must ensure the
security domain referenced by your _sasl-authentication-factory_
references a security realm that contains the _$local_ user. By default,
WildFly provides the _local_ identity realm that provides this user.

[[add-silent-authentication-to-an-existing-sasl-authentication-factory.]]
==== Add silent authentication to an existing
sasl-authentication-factory.

[source,options="nowrap"]
----
/subsystem=elytron/sasl-authentication-factory=example-sasl-auth:list-add(name=mechanism-configurations, value={mechanism-name=JBOSS-LOCAL-USER, realm-mapper=local})
 
reload
----

[[create-a-new-sasl-server-factory-with-silent-authentication.]]
==== Create a new sasl-server-factory with silent authentication.

[source,options="nowrap"]
----
/subsystem=elytron/sasl-authentication-factory=example-sasl-auth:add(sasl-server-factory=configured,security-domain=exampleSD,mechanism-configurations=[{mechanism-name=DIGEST-MD5,mechanism-realm-configurations=[{realm-name=exampleManagementRealm}]},{mechanism-name=JBOSS-LOCAL-USER, realm-mapper=local}])
 
reload
----

[[remove-silent-authentication-from-an-existing-sasl-server-factory]]
==== Remove silent authentication from an existing sasl-server-factory:

[source,options="nowrap"]
----
/subsystem=elytron/sasl-authentication-factory=managenet-sasl-authentication:read-resource
{
    "outcome" => "success",
    "result" => {
        "mechanism-configurations" => [
            {
                "mechanism-name" => "JBOSS-LOCAL-USER",
                "realm-mapper" => "local"
            },
            {
                "mechanism-name" => "DIGEST-MD5",
                "mechanism-realm-configurations" => [{"realm-name" => "ManagementRealm"}]
            }
        ],
        "sasl-server-factory" => "configured",
        "security-domain" => "ManagementDomain"
    }
}
 
/subsystem=elytron/sasl-authentication-factory=temp-sasl-authentication:list-remove(name=mechanism-configurations,index=0)
 
reload
----

[[using-rbac-with-elytron]]
=== Using RBAC with Elytron

RBAC can be configured to automatically assign or exclude roles for
users that are members of groups. This is configured in the
_access-control_ section of the core management. When the management
interfaces are secured with the _elytron_ subsystem, and users are
assigned groups when they authenticate. You can also configure roles to
be assigned to authenticated users in a variety of ways using the
_elytron_ subsystem, for example using a role mapper or a role decoder.

[[configure-ssltls]]
== Configure SSL/TLS

[[enable-one-way-ssltls-for-applications]]
=== Enable One-way SSL/TLS for Applications

There are a couple ways to enable one-way SSL/TLS for deployed applications.

[[one-way-ssl-applications-using-security-command]]
==== Using a security command:

The _security enable-ssl-http-server_ command can be used to enable one-way
SSL/TLS for deployed applications. Example of wizard usage:

[source,java,options="nowrap"]
----
security enable-ssl-http-server --interactive
Please provide required pieces of information to enable SSL:
Key-store file name (default default-server.keystore): keystore.jks
Password (blank generated): secret
What is your first and last name? [Unknown]: localhost
What is the name of your organizational unit? [Unknown]:
What is the name of your organization? [Unknown]:
What is the name of your City or Locality? [Unknown]:
What is the name of your State or Province? [Unknown]:
What is the two-letter country code for this unit? [Unknown]:
Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct y/n [y]?
Validity (in days, blank default): 365
Alias (blank generated): localhost
Enable SSL Mutual Authentication y/n (blank n): n

SSL options:
key store file: keystore.jks
distinguished name: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
password: secret
validity: 365
alias: localhost
Server keystore file keystore.jks, certificate file keystore.pem and keystore.csr file
will be generated in server configuration directory.
Do you confirm y/n: y
----
NB: Once the command is executed, the CLI will reload the server. On JDK17 kind of configuration you must 
add the _--override-ssl-context_ argument in order to replace the default SSL context. 

HTTPS is now enabled for applications.

[[one-way-ssl-applications-using-elytron-subsystem-commands]]
==== Using Elytron subsystem commands:

You can also use the Elytron subsystem, along with the Undertow subsystem, to
enable HTTPS for deployed applications.

[[configure-a-key-store-in-wildfly]]
===== Configure a key-store in WildFly:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:add(path=/path/to/keystore.jks,credential-reference={clear-text=secret},type=JKS)
----

The previous command uses an absolute path to the keystore.
Alternatively you can use the _relative-to_ attribute to specify the
base directory variable and _path_ specify a relative path.
Also, in case of file-based keystore the _type_ attribute can be omitted and
the keystore type will be automatically detected.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:add(path=keystore.jks,relative-to=jboss.server.config.dir,credential-reference={clear-text=secret},type=JKS)
----

If the keystore file does not exist yet, the following commands can be used to
generate an example key pair:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:generate-key-pair(alias=localhost,algorithm=RSA,key-size=1024,validity=365,credential-reference={clear-text=secret},distinguished-name="CN=localhost")
/subsystem=elytron/key-store=httpsKS:store()
----

[[configure-a-key-manager-in-that-references-your-key-store]]
===== Configure a key-manager that references your key-store:

[source,options="nowrap"]
----
/subsystem=elytron/key-manager=httpsKM:add(key-store=httpsKS,credential-reference={clear-text=secret})
----

[[configure-a-server-ssl-context-in-that-references-your-key-manager]]
===== Configure a server-ssl-context that references your key-manager:

[source,options="nowrap"]
----
/subsystem=elytron/server-ssl-context=httpsSSC:add(key-manager=httpsKM,protocols=["TLSv1.2"])
----

*IMPORTANT*: You need to determine what SSL/TLS protocols you want to
support. The example commands above uses _TLSv1.2_.

[[check-and-see-if-the-https-listener-is-configured-to-use-a-legacy-security-realm-for-its-ssl-configuration]]
===== Check and see if the https-listener is configured to use a legacy security realm for its SSL configuration:

[source,options="nowrap"]
----
/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 _ApplicationRealm_ legacy security realm for its SSL configuration.
Undertow cannot reference both a legacy security realm and an
_ssl-context_ in Elytron at the same time so you must remove the
reference to the legacy security realm. Also there has to be always
configured either _ssl-context_ or _security-realm_. Thus when changing
between those, you have to use batch operation:

*Remove the reference to the legacy security realm and update the*
*_https-listener_* *to use the* *_ssl-context_* *from Elytron* *:*

[source,options="nowrap"]
----
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=httpsSSC)
run-batch
----

[[reload-the-server]]
===== Reload the server:

[source,options="nowrap"]
----
reload
----

HTTPS is now enabled for applications.

[[enable-two-way-ssltls-in-wildfly-for-applications]]
=== Enable Two-way SSL/TLS in WildFly for Applications

First, obtain or generate your client keystore.

[source,options="nowrap"]
----
$ keytool -genkeypair -alias client -keyalg RSA -keysize 1024 -validity 365 -keystore client.keystore.jks -dname "CN=client" -keypass secret -storepass secret
----

Export the client certificate:

[source,options="nowrap"]
----
$ keytool -exportcert  -keystore client.keystore.jks -alias client -keypass secret -storepass secret -file /path/to/client.cer
----

There are a couple ways to enable two-way SSL/TLS for deployed applications.

[[two-way-ssl-applications-using-security-command]]
==== Using a security command:

The _security enable-ssl-http-server_ command can be used to enable two-way
SSL/TLS for the deployed applications. Example of wizard usage:

[source,java,options="nowrap"]
----
security enable-ssl-http-server --interactive
Please provide required pieces of information to enable SSL:
Key-store file name (default default-server.keystore): server.keystore.jks
Password (blank generated): secret
What is your first and last name? [Unknown]: localhost
What is the name of your organizational unit? [Unknown]:
What is the name of your organization? [Unknown]:
What is the name of your City or Locality? [Unknown]:
What is the name of your State or Province? [Unknown]:
What is the two-letter country code for this unit? [Unknown]:
Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct y/n [y]?
Validity (in days, blank default): 365
Alias (blank generated): localhost
Enable SSL Mutual Authentication y/n (blank n): y
Client certificate (path to pem file): /path/to/client.cer
Validate certificate y/n (blank y):
Trust-store file name (management.truststore): server.truststore.jks
Password (blank generated): secret

SSL options:
key store file: server.keystore.jks
distinguished name: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
password: secret
validity: 365
alias: localhost
client certificate: /path/to/client.cer
trust store file: server.trustore.jks
trust store password: secret
Server keystore file server.keystore.jks, certificate file server.pem and server.csr file will be generated in server configuration directory.
Server truststore file server.trustore.jks will be generated in server configuration directory.
Do you confirm y/n: y
----
NB: Once the command is executed, the CLI will reload the server.On JDK17 kind of configuration you must 
add the _--override-ssl-context_ argument in order to replace the default SSL context. To complete
the two-way SSL/TLS authentication, you need to
<<import-server-certificate-into-client-truststore-applications,import the server certificate>>
into the client truststore and
<<configure-your-client-to-use-the-client-certificate-applications,configure your client>>
to present the client certificate.

[[two-way-ssl-applications-using-elytron-subsystem-commands]]
==== Using Elytron subsystem commands:

You can also use the Elytron subsystem, along with the Undertow subsystem,
to enable two-way SSL/TLS for deployed applications.

[[obtain-or-generate-your-keystores-applications]]
===== Obtain or generate your key stores:

Before enabling HTTPS in WildFly, you must obtain or generate the server key
store and trust store you plan on using. To generate an example key store and
trust store, use the following commands.

Create a server key-store:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=twoWayKS:add(path=/path/to/server.keystore.jks,credential-reference={clear-text=secret},type=JKS)
/subsystem=elytron/key-store=twoWayKS:generate-key-pair(alias=localhost,algorithm=RSA,key-size=1024,validity=365,credential-reference={clear-text=secret},distinguished-name="CN=localhost")
/subsystem=elytron/key-store=twoWayKS:store()
----

*NOTE* +
The first command above uses an absolute path to the keystore.
Alternatively you can use the _relative-to_ attribute to specify the
base directory variable and _path_ specify a relative path.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=twoWayKS:add(path=server.keystore.jks,relative-to=jboss.server.config.dir,credential-reference={clear-text=secret},type=JKS)
----

Export the server certificate:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=twoWayKS:export-certificate(alias=localhost,path=/path/to/server.cer,pem=true)
----

[[import-client-certificate]]
Create a key-store for the server truststore and import the client certificate
into the server truststore:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=twoWayTS:add(path=/path/to/server.truststore.jks,credential-reference={clear-text=secret},type=JKS)
/subsystem=elytron/key-store=twoWayTS:import-certificate(alias=client,path=/path/to/client.cer,credential-reference={clear-text=secret},trust-cacerts=true)
/subsystem=elytron/key-store=twoWayTS:store()
----

[[configure-a-key-manager-in-that-references-your-key-store-key-store]]
===== Configure a key-manager that references your key store key-store:

[source,options="nowrap"]
----
/subsystem=elytron/key-manager=twoWayKM:add(key-store=twoWayKS,credential-reference={clear-text=secret})
----

[[configure-a-trust-manager-in-that-references-your-truststore-key-store]]
===== Configure a trust-manager that references your truststore key-store:

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=twoWayTM:add(key-store=twoWayTS)
----

[[configure-a-server-ssl-context-in-that-references-your-key-manager-trust-manager-and-enables-client-authentication]]
===== Configure a server-ssl-context that references your key-manager, trust-manager, and enables client authentication:

[source,options="nowrap"]
----
/subsystem=elytron/server-ssl-context=twoWaySSC:add(key-manager=twoWayKM,protocols=["TLSv1.2"],trust-manager=twoWayTM,need-client-auth=true)
----

*IMPORTANT* +
You need to determine what SSL/TLS protocols you want to support. The
example commands above uses _TLSv1.2_.

[[check-and-see-if-the-https-listener-is-configured-to-use-a-legacy-security-realm-for-its-ssl-configuration-1]]
===== Check and see if the https-listener is configured to use a legacy security realm for its SSL configuration:

[source,options="nowrap"]
----
/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 _ApplicationRealm_ legacy security realm for its SSL configuration.
Undertow cannot reference both a legacy security realm and an
_ssl-context_ in Elytron at the same time so you must remove the
reference to the legacy security realm. Also there has to be always
configured either _ssl-context_ or _security-realm_. Thus when changing
between those, you have to use batch operation:

[[remove-the-reference-to-the-legacy-security-realm-and-update-the-https-listener-to-use-the-ssl-context-from-elytron]]
===== Remove the reference to the legacy security realm and update the
https-listener to use the ssl-context from Elytron:

[source,options="nowrap"]
----
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=twoWaySSC)
run-batch
----

[[reload-the-server-1]]
===== Reload the server

[source,options="nowrap"]
----
reload
----

To complete the two-way SSL/TLS authentication, you need to
<<import-server-certificate-into-client-truststore-applications,import the server certificate>>
into the client truststore and
<<configure-your-client-to-use-the-client-certificate-applications,configure your client>>
to present the client certificate.

[[import-server-certificate-into-client-truststore-applications]]
==== Import the server certificate into the client truststore

[source,options="nowrap"]
----
$ keytool -importcert -keystore client.truststore.jks -storepass secret -alias localhost -trustcacerts -file /path/to/server.cer
----

[[configure-your-client-to-use-the-client-certificate-applications]]
==== Configure your client to use the client certificate

You need to configure your client to present the trusted client
certificate to the server to complete the two-way SSL/TLS
authentication. For example, if using a browser, you need to import the
trusted certificate into the browser's truststore.

Two-Way HTTPS is now enabled for applications.


[[configure-certificate-revocation-in-trust-manager]]
=== Configure certificate revocation in trust-manager


[[configure-certificate-revocation-list]]
==== Configure Certificate Revocation List:

You can configure your trust-manager to use certificate-revocation-list (CRL) to check revocation status of obtained certificates.

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=twoWayTM:write-attribute(name=certificate-revocation-list, value={})
----

This will use CRLs obtained from distribution points referenced in your certificates.

*NOTE:* To use a CRL your trust store must contain the certificate chain in order to check validity of both CRL list.

[[override-crl-location-obtained-from-certificates]]
===== Override CRL location obtained from certificates:

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=twoWayTM:write-attribute(name=certificate-revocation-list.path, value=intermediate.crl.pem)
----

[[configure-ocsp-certificate-revocation]]
==== Configure OCSP certificate revocation:

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=twoWayTM:write-attribute(name=ocsp, value={})
----

This will enable OCSP certificate revocation by using OCSP responder inside the certificate. In case the responder is known but OCSP revocation status is unknown, the verification will fail.

[[override-ocsp-responder-uri-extracted-from-certificate]]
===== Override OCSP responder URI extracted from certificate:

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=twoWayTM:write-attribute(name=ocsp.responder, value="http://example.com/ocsp-responder")
----

[[configure-order-of-certificate-revocation-mechanisms]]
==== Configure order of revocation mechanisms:

If both CRL and OCSP are defined, Elytron will use OCSP for obtaining revocation status as first by default. In case you want to prefer CRL:

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=twoWayTM:write-attribute(name=ocsp.prefer-crls, value="true")
----

[[other-trust-manager-configuration]]
==== Other trust-manager configuration:

[[configure-trust-manager-to-only-check-leaf-certificates-for-revocation-status]]
===== Configure trust-manager to only check leaf certificates for revocation status

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=twoWayTM:write-attribute(name=only-leaf-cert, value="true")
----

[[configure-trust-manager-to-accept-certificates-with-unknown-revocation-status]]
===== Configure trust-manager to accept certificates with unknown revocation status
In case you want to accept certificates with unknown revocation status, you can enable soft-fail behaviour in your trust-manager.

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=twoWayTM:write-attribute(name=soft-fail, value=true)
----

[[set-maximum-number-of-intermediate-certificates-of-trust-manager]]
===== Set maximum number of intermediate certificates of trust-manager

Sets the value of the maximum number of non-self-issued intermediate certificates that may exist in a certification path with default value of 5.

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=twoWayTM:write-attribute(name=maximum-cert-path, value=10)
----

[[enable-one-way-ssltls-for-the-management-interfaces]]
=== Enable One-way SSL/TLS for the Management Interfaces

There are a couple ways to enable one-way SSL/TLS for the management interfaces.

[[one-way-ssl-management-interfaces-using-security-command]]
==== Using a security command:

The _security enable-ssl-management_ command can be used to enable one-way
SSL/TLS for the management interfaces. Example of wizard usage:

[source,java,options="nowrap"]
----
security enable-ssl-management --interactive
Please provide required pieces of information to enable SSL:
Key-store file name (default management.keystore): keystore.jks
Password (blank generated): secret
What is your first and last name? [Unknown]: localhost
What is the name of your organizational unit? [Unknown]:
What is the name of your organization? [Unknown]:
What is the name of your City or Locality? [Unknown]:
What is the name of your State or Province? [Unknown]:
What is the two-letter country code for this unit? [Unknown]:
Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct y/n [y]?
Validity (in days, blank default): 365
Alias (blank generated): localhost
Enable SSL Mutual Authentication y/n (blank n): n

SSL options:
key store file: keystore.jks
distinguished name: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
password: secret
validity: 365
alias: localhost
Server keystore file keystore.jks, certificate file keystore.pem and keystore.csr file
will be generated in server configuration directory.
Do you confirm y/n :y
----
NB: Once the command is executed, the CLI will reload the server and reconnect to it.

HTTPS is now enabled for the management interfaces.

[[one-way-ssl-management-interfaces-using-elytron-subsystem-commands]]
==== Using Elytron subsystem commands:

Elytron subsystem commands can also be used to enable one-way SSL/TLS for the
management interfaces.

[[configure-key-store]]
===== Configure a key-store:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:add(path=keystore.jks,relative-to=jboss.server.config.dir,credential-reference={clear-text=secret},type=JKS)
----

*NOTE:* The above command uses _relative-to_ to reference the location
of the keystore file. Alternatively, you can specify the full path to
the keystore in _path_ and omit _relative-to_.

If the keystore file does not exist yet, the following commands can be used to
generate an example key pair:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:generate-key-pair(alias=localhost,algorithm=RSA,key-size=1024,validity=365,credential-reference={clear-text=secret},distinguished-name="CN=localhost")
/subsystem=elytron/key-store=httpsKS:store()
----

[[create-a-key-manager-and-server-ssl-context]]
===== Create a key-manager and server-ssl-context.

[source,options="nowrap"]
----
/subsystem=elytron/key-manager=httpsKM:add(key-store=httpsKS,credential-reference={clear-text=secret})
 
/subsystem=elytron/server-ssl-context=httpsSSC:add(key-manager=httpsKM,protocols=["TLSv1.2"])
----

*IMPORTANT:* You need to determine what SSL/TLS protocols you want to
support. The example commands above uses _TLSv1.2_.

[[enable-https-on-the-management-interface.]]
===== Enable HTTPS on the management interface.

[source,options="nowrap"]
----
/core-service=management/management-interface=http-interface:write-attribute(name=ssl-context, value=httpsSSC)
 
/core-service=management/management-interface=http-interface:write-attribute(name=secure-socket-binding, value=management-https)
----

[[reload-the-wildfly-instance.]]
===== Reload the WildFly instance.

[source,options="nowrap"]
----
reload
----

HTTPS is now enabled for the management interfaces.

[[enable-two-way-ssltls-for-the-management-interfaces]]
=== Enable Two-way SSL/TLS for the Management Interfaces

First, obtain or generate your client keystore.

[source,options="nowrap"]
----
$ keytool -genkeypair -alias client -keyalg RSA -keysize 1024 -validity 365 -keystore client.keystore.jks -dname "CN=client" -keypass secret -storepass secret
----

Export your client certificate.

[source,options="nowrap"]
----
$ keytool -exportcert  -keystore client.keystore.jks -alias client -keypass secret -storepass secret -file /path/to/client.cer
----

There are a couple ways to enable two-way SSL/TLS for the management interfaces.

[[two-way-ssl-management-interfaces-using-security-command]]
==== Using a security command:

The _security enable-ssl-management_ command can be used to enable two-way
SSL/TLS for the management interfaces. Example of wizard usage:

[source,java,options="nowrap"]
----
security enable-ssl-management --interactive
Please provide required pieces of information to enable SSL:
Key-store file name (default management.keystore): server.keystore.jks
Password (blank generated): secret
What is your first and last name? [Unknown]: localhost
What is the name of your organizational unit? [Unknown]:
What is the name of your organization? [Unknown]:
What is the name of your City or Locality? [Unknown]:
What is the name of your State or Province? [Unknown]:
What is the two-letter country code for this unit? [Unknown]:
Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct y/n [y]?
Validity (in days, blank default): 365
Alias (blank generated): localhost
Enable SSL Mutual Authentication y/n (blank n): y
Client certificate (path to pem file): /path/to/client.cer
Validate certificate y/n (blank y):
Trust-store file name (management.truststore): server.truststore.jks
Password (blank generated): secret

SSL options:
key store file: server.keystore.jks
distinguished name: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
password: secret
validity: 365
alias: localhost
client certificate: /path/to/client.cer
trust store file: server.trustore.jks
trust store password: secret
Server keystore file server.keystore.jks, certificate file server.pem and server.csr file will be generated in server configuration directory.
Server truststore file server.trustore.jks will be generated in server configuration directory.
Do you confirm y/n: y
----
NB: Once the command is executed, the CLI will reload the server and
attempt to reconnect to it. To complete the two-way SSL/TLS authentication,
you need to <<import-server-certificate-into-client-truststore-management,import the server certificate>>
into the client truststore and
<<configure-your-client-to-use-the-client-certificate-management,configure your client>>
to present the client certificate.

[[two-way-ssl-management-interfaces-using-elytron-subsystem-commands]]
==== Using Elytron subsystem commands:

Elytron subsystem commands can also be used to enable two-way SSL/TLS for the
management interfaces.

[[obtain-or-generate-your-key-stores-management]]
===== Obtain or generate your key stores.

Before enabling HTTPS in WildFly, you must obtain or generate the server
key store and trust store you plan on using. To generate an example key
store and trust store, use the following commands.

Configure a key-store.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=twoWayKS:add(path=server.keystore.jks,relative-to=jboss.server.config.dir,credential-reference={clear-text=secret},type=JKS)

/subsystem=elytron/key-store=twoWayKS:generate-key-pair(alias=localhost,algorithm=RSA,key-size=1024,validity=365,credential-reference={clear-text=secret},distinguished-name="CN=localhost")

/subsystem=elytron/key-store=twoWayKS:store()
----

*NOTE:* The above command uses _relative-to_ to reference the location
of the keystore file. Alternatively, you can specify the full path to
the keystore in _path_ and omit _relative-to_.

Export your server certificate.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=twoWayKS:export-certificate(alias=localhost,path=/path/to/server.cer,pem=true)
----

[[import-client-certificate-into-server-truststore]]
Create a key-store for the server trust store and import the client certificate
into the server trust store.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=twoWayTS:add(path=server.truststore.jks,relative-to=jboss.server.config.dir,credential-reference={clear-text=secret},type=JKS)

/subsystem=elytron/key-store=twoWayTS:import-certificate(alias=client,path=/path/to/client.cer,credential-reference={clear-text=secret},trust-cacerts=true)

/subsystem=elytron/key-store=twoWayTS:store()
----

[[configure-a-key-manager-trust-manager-and-server-ssl-context-for-the-server-key-store-and-trust-store]]
===== Configure a key-manager, trust-manager, and server-ssl-context for the server key store and trust store.

[source,options="nowrap"]
----
/subsystem=elytron/key-manager=twoWayKM:add(key-store=twoWayKS,credential-reference={clear-text=secret})
 
/subsystem=elytron/trust-manager=twoWayTM:add(key-store=twoWayTS)
 
/subsystem=elytron/server-ssl-context=twoWaySSC:add(key-manager=twoWayKM,protocols=["TLSv1.2"],trust-manager=twoWayTM,want-client-auth=true,need-client-auth=true)
----

*IMPORTANT:* You need to determine what SSL/TLS protocols you want to
support. The example commands above uses _TLSv1.2_.

[[enable-https-on-the-management-interface.-1]]
===== Enable HTTPS on the management interface.

[source,options="nowrap"]
----
/core-service=management/management-interface=http-interface:write-attribute(name=ssl-context, value=twoWaySSC)
 
/core-service=management/management-interface=http-interface:write-attribute(name=secure-socket-binding, value=management-https)
----

[[reload-the-wildfly-instance.-1]]
===== Reload the WildFly instance.

[source,options="nowrap"]
----
reload
----

To complete the two-way SSL/TLS authentication, you need to
<<import-server-certificate-into-client-truststore-management,import the server certificate>>
into the client truststore and
<<configure-your-client-to-use-the-client-certificate-management,configure your client>>
to present the client certificate.

[[import-server-certificate-into-client-truststore-management]]
==== Import the server certificate into the client truststore.

[source,options="nowrap"]
----
$ keytool -importcert -keystore client.truststore.jks -storepass secret -alias localhost -trustcacerts -file /path/to/server.cer
----

[[configure-your-client-to-use-the-client-certificate-management]]
==== Configure your client to use the client certificate.

You need to configure your client to present the trusted client
certificate to the server to complete the two-way SSL/TLS
authentication. For example, if using a browser, you need to import the
trusted certificate into the browser's trust store.

Two-way SSL/TLS is now enabled for the management interfaces.


[[keystore-manipulation-operations]]
=== KeyStore manipulation operations

It is possible to perform various KeyStore manipulation operations on an
Elytron key-store resource using the management CLI.

[[generate-key-pair]]
==== Generate a key pair
The _generate-key-pair_ command generates a key pair and wraps the resulting
public key in a self-signed X.509 certificate. The generated private key and
self-signed certificate will be added to the KeyStore.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:generate-key-pair(alias=example,algorithm=RSA,key-size=1024,validity=365,credential-reference={clear-text=secret},distinguished-name="CN=www.example.com")
----

[[generate-certificate-signing-request]]
==== Generate a certificate signing request
The _generate-certificate-signing-request_ command generates a PKCS #10
certificate signing request using a PrivateKeyEntry from the KeyStore. The
generated certificate signing request will be output to a file.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:generate-certificate-signing-request(alias=example,path=server.csr,relative-to=jboss.server.config.dir,distinguished-name="CN=www.example.com",extensions=[{critical=false,name=KeyUsage,value=digitalSignature}],credential-reference={clear-text=secret})
----

[[import-certificate]]
==== Import a certificate or certificate chain
The _import-certificate_ command imports a certificate or certificate chain
from a file into an entry in the KeyStore.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:import-certificate(alias=example,path=/path/to/certificate_or_chain/file,relative-to=jboss.server.config.dir,credential-reference={clear-text=secret},trust-cacerts=true)
----

[[export-certificate]]
==== Export a certificate
The _export-certificate_ command exports a certificate from an entry in the
KeyStore to a file.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:export-certificate(alias=example,path=serverCert.cer,relative-to=jboss.server.config.dir,pem=true)
----

[[change-alias]]
==== Change an alias
The _change-alias_ command moves an existing KeyStore entry to a new alias.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:change-alias(alias=example,new-alias=newExample,credential-reference={clear-text=secret})
----

[[store-changes]]
==== Store changes made to key-stores
The _store_ command persists any changes that have been made to the file that
backs the KeyStore.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:store()
----

[[obtain-certificate]]
==== Obtain a signed certificate from Let's Encrypt
Before obtaining a signed certificate from Let's Encrypt, you must configure
a Let's Encrypt account using the following commands.

[[create-le-account-key-store]]
===== Create a key-store to hold your Let's Encrypt account key.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=accountsKS:add(path=accounts.keystore.jks,relative-to=jboss.server.config.dir,credential-reference={clear-text=secret},type=JKS)
----

[[configure-le-account]]
===== Configure a Let's Encrypt account

[source,options="nowrap"]
----
/subsystem=elytron/certificate-authority-account=myLEAccount:add(alias=example,key-store=accountsKS,contact-urls=[mailto:admin@example.org])
----

*Note:* Let's Encrypt is the default certificate authority and therefore the `certificate-authority` attribute can be omitted when creating a `certificate-authority-account`.
It is also possible to configure an account with different certificate authority than Let's Encrypt by adding custom `certificate-authority` resource and passing it to `certificate-authority-account`.
[source,options="nowrap"]
----
/subsystem=elytron/certificate-authority=myCA:add(url="https://my.example.url/acme/directory", staging-url="https://my.example.staging.url/acme/directory")
/subsystem=elytron/certificate-authority-account=myCAAccount:add(certificate-authority=myCA,alias=example,key-store=accountsKS,contact-urls=[mailto:admin@example.org])
----
[[obtain-signed-certificate]]
===== Obtain a signed certificate from Let's Encrypt

The _obtain-certificate_ command creates an account with Let's Encrypt, if such an account does not already exist,
obtains a signed certificate from Let's Encrypt, and stores it in the KeyStore.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:obtain-certificate(alias=server,domain-names=[www.example.org],certificate-authority-account=myLEAccount,agree-to-terms-of-service=true,algorithm=RSA,key-size=1024,credential-reference={clear-text=secret})
----

[[revoke-certificate]]
==== Revoke a signed certificate

The _revoke-certificate_ command revokes a certificate that was issued by Let's Encrypt.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:revoke-certificate(alias=server,reason=keyCompromise,certificate-authority-account=myLEAccount)
----

[[should-renew-certificate]]
==== Check if a certificate is due for renewal

The _should-renew-certificate_ command checks if a certificate is due for renewal. In particular, it will return true if the certificate expires in less than the given number of days and false otherwise.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:should-renew-certificate(alias=server,expiration=7)
----

[[certificate-authority-account-operations]]
=== Certificate authority account operations

It is possible to perform various operations on an Elytron certificate-authority-account
resource using the management CLI.

[[create-account]]
==== Create an account with the certificate authority

The _create-account_ command creates an account with the certificate authority if one does not already exist.

[source,options="nowrap"]
----
/subsystem=elytron/certificate-authority-account=myLEAccount:create-account(agree-to-terms-of-service=true)
----

[[update-account]]
==== Update an account with the certificate authority

The _update-account_ command updates an account with the certificate authority.

[source,options="nowrap"]
----
/subsystem=elytron/certificate-authority-account=myLEAccount:update-account(agree-to-terms-of-service=true)
----

[[change-account-key]]
==== Change the account key

The _change-account-key_ command changes the key associated with the certificate authority account.

[source,options="nowrap"]
----
/subsystem=elytron/certificate-authority-account=myLEAccount:change-account-key()
----

[[deactivate-account]]
==== Deactivate the account

The _deactivate-account_ command deactivates the certificate authority account.

[source,options="nowrap"]
----
/subsystem=elytron/certificate-authority-account=myLEAccount:deactivate-account()
----

[[get-metadata]]
==== Get metadata

The _get-metadata_ command retrieves the metadata (e.g., terms of service URL, website URL, CAA identities,
and whether or not an external account is required), if any, associated with the certificate authority.

[source,options="nowrap"]
----
/subsystem=elytron/certificate-authority-account=myLEAccount:get-metadata()
----

[[using-an-ldap-key-store]]
=== Using an ldap-key-store

An _ldap-key-store_ allows you to use a keystore stored in an LDAP
server. You can use an _ldap-key-store_ in same way you can use a
_key-store_.

To create and use an _ldap-key-store_:

[[configure-a-dir-context.]]
==== Configure a dir-context.

To connect to the LDAP server from WildFly, you need to configure a
_dir-context_ that provides the URL as well as the principal used to
connect to the server.

*Example dir-context*

[source,options="nowrap"]
----
/subsystem=elytron/dir-context=exampleDC:add( \
  url="ldap://127.0.0.1:10389", \
  principal="uid=admin,ou=system", \
  credential-reference={clear-text=secret} \
)
----

[[configure-an-ldap-key-store.]]
==== Configure an ldap-key-store.

When configure an _ldap-key-store_, you need to specify both the
_dir-context_ used to connect to the LDAP server as well as how to
locate the keystore stored in the LDAP server. At a minimum, this
requires you specify a _search-path_.

*Example ldap-key-store*

[source,options="nowrap"]
----
/subsystem=elytron/ldap-key-store=ldapKS:add( \
  dir-context=exampleDC, \
  search-path="ou=Keystores,dc=wildfly,dc=org" \
)
----

[[use-the-ldap-key-store.]]
==== Use the ldap-key-store.

Once you have defined your _ldap-key-store_, you can use it in the same
places where a _key-store_ could be used. For example, you could use an
_ldap-key-store_ when configuring HTTPS and Two-Way HTTPS for
applications.

[[using-a-filtering-key-store]]
=== Using a filtering-key-store

A _filtering-key-store_ allows you to expose a subset of aliases from an
existing _key-store_, and use it in the same places you could use a
_key-store_. For example, if a keystore contained _alias1_, _alias2_,
and _alias3_, but you only wanted to expose _alias1_ and _alias3_, a
_filtering-key-store_ provides you several ways to do that.

To create a _filtering-key-store_:

[[configure-a-key-store.]]
==== Configure a key-store.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=myKS:add( \
  path=keystore.jks, \
  relative-to=jboss.server.config.dir, \
  credential-reference={ \
    clear-text=secret \
  }, \
  type=JKS \
)
----

[[configure-a-filtering-key-store.]]
==== Configure a filtering-key-store.

When you configure a _filtering-key-store_, you specify which
_key-store_ you want to filter and the _alias-filter_ for filtering
aliases from the _key-store_. The filter can be specified in one of the
following formats:

* _alias1,alias3_, which is a comma-delimited list of aliases to expose.
* _ALL:-alias2_, which exposes all aliases in the keystore except the
ones listed.
* _NONE:+alias1:+alias3_, which exposes no aliases in the keystore
except the ones listed.

This example uses a comma-delimted list to expose _alias1_ and _alias3_.

[source,options="nowrap"]
----
/subsystem=elytron/filtering-key-store=filterKS:add( \
  key-store=myKS, \
  alias-filter="alias1,alias3" \
)
----

[[use-the-filtering-key-store.]]
==== Use the filtering-key-store.

Once you have defined your _filtering-key-store_, you can use it in the
same places where a _key-store_ could be used. For example, you could
use a _filtering-key-store_ when configuring HTTPS and Two-Way HTTPS for
applications.

[[reload-a-keystore]]
=== Reload a Keystore

You can reload a keystore configured in WildFly from the management CLI.
This is useful in cases where you have made changes to certificates
referenced by a keystore.

To reload a keystore.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:load
----

[[reinitialize-a-key-manager]]
=== Reinitialize a Key Manager

You can reinitialize a key-manager configured in WildFly from the management CLI.
This is useful in cases where you have made changes in certificates provided by keystore
resource and you want to apply this change to new SSL connections without restarting the server.

If the key-store is file based then it must be loaded first.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:load()
----

To reinitialize a key-manager.

[source,options="nowrap"]
----
/subsystem=elytron/key-manager=httpsKM:init()
----

[[reinitialize-a-trust-manager]]
=== Reinitialize a Trust Manager

You can reinitialize a trust-manager configured in WildFly from the management CLI.
This is useful in cases where you have made changes to certificates provided by keystore
resource and you want to apply this change to new SSL connections without restarting the server.

If the key-store is file based then it must be loaded first.

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS:load()
----

To reinitialize a trust-manager.

[source,options="nowrap"]
----
/subsystem=elytron/trust-manager=httpsTM:init()
----

[[check-the-content-of-a-keystore-by-alias]]
=== Check the Content of a Keystore by Alias

If you add a keystore to the _elytron_ subsystem using the _key-store_
component, you can check the keystore's contents using the _alias_ child
element and reading its attributes.

For example:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=httpsKS/alias=localhost:read-attribute(name=certificate-chain)
{
    "outcome" => "success",
    "result" => [{
        "type" => "X.509",
        "algorithm" => "RSA",
        "format" => "X.509",
        "public-key" => "30:81:9f:30:0d:06:09:2a:8......
----

The following attributes can be read:

[cols=",",options="header"]
|=======================================================================
|Attribute |Description

|certificate |The certificate associated with the alias. If the alias
has a certificate chain this will always be undefined.

|certificate-chain |The certificate chain associated with the alias.

|creation-date |The creation date of the entry represented by this
alias.

|entry-type |The type of the entry for this alias. Available types:
PasswordEntry, PrivateKeyEntry, SecretKeyEntry, TrustedCertificateEntry,
and Other. Unrecognized types will be reported as Other.
|=======================================================================

[[custom-components]]
=== Custom Components

When configuring SSL/TLS in the _elytron_ subsystem, you can provide and
use custom implementations of the following components:

* _key-store_
* _key-manager_
* _trust-manager_
* _client-ssl-context_
* _server-ssl-context_
* _certificate-authority-account_

When creating custom implementations of Elytron components, they must
present the appropriate capabilities and requirements.

[[configuring-a-server-sslcontext]]
=== Configuring a server SSLContext

Using the Elytron subsystem, it is possible to configure an `SSLContext` for use on the server side of a connection.

Adding a server `SSLContext` takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/server-ssl-context=test-server-ssl-context:add(...)
----

The following attributes can be specified when creating a `server-ssl-context`:

security-domain:: _(Optional)_ A reference to the `security-domain` to use for authentication during SSL session
establishment.
key-manager:: _(Optional)_ A reference to the `KeyManager` to be used by this `SSLContext`.
trust-manager:: _(Optional)_ A reference to the `TrustManager` to be used by this `SSLContext`.
cipher-suite-filter:: _(Optional)_ The filter to be applied to the cipher suites for TLSv1.2 and below made available
by this SSLContext. The format of this attribute is described in detail in
http://wildfly-security.github.io/wildfly-elytron/master/org/wildfly/security/ssl/CipherSuiteSelector.html#fromString-java.lang.String-[org.wildfly.security.ssl.CipherSuiteSelector.fromString(selector)].
The default value is `DEFAULT`, which corresponds to all known cipher suites that do not have NULL encryption and
excludes any cipher suites that have no authentication.
cipher-suite-names:: _(Optional)_ The enabled cipher suites for TLSv1.3. The format of this attribute is a simple colon
(":") separated list of TLSv1.3 cipher suite names (e.g., `TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256`).
This attribute must be specified in order for TLSv1.3 to be enabled.
protocols:: _(Optional)_ A space separated list of the protocols to be supported by this `SSLContext`. The default value
is `TLSv1 TLSv1.1 TLSv1.2 TLSv1.3`. Note that the TLSv1.3 protocol will only be usable when running against JDK 11 or
higher.
want-client-auth:: _(Optional)_ To request (but not to require) a client certificate on SSL handshake. If a
`security-domain` is configured and supports X509 evidence, this will be set to `true` automatically. Ignored when
`need-client-auth` is set. The default value is `false`.
need-client-auth:: _(Optional)_ If `true`, a client certificate is required on SSL handshake. A connection without a
trusted client certificate will be rejected. The default value is `false`.
authentication-optional:: _(Optional)_ Rejection of the client certificate by the configured `security-domain` will not
prevent the connection. This allows a fall through to use other authentication mechanisms (like form login) when the
client certificate is rejected by the
`security-domain`. This has an effect only when the `security-domain` is configured. The default value is `false`.
use-cipher-suites-order:: _(Optional)_ If `true`, the cipher suites order defined on the server will be used. If `false`,
the cipher suites order presented by the client will be used. The default value is `true`.
provider-name:: _(Optional)_ The name of the provider to use. If not specified, all providers from `providers` will be
passed to the `SSLContext`.
providers:: _(Optional)_ The name of the providers to obtain the `Provider[]` to use to load the `SSLContext`.
maximum-session-cache-size:: _(Optional)_ The maximum number of SSL sessions to be cached. The default value `-1`
indicates that the JVM default value should be used. A value of `0` means there is no limit.
session-timeout:: _(Optional)_ The timeout for SSL sessions. The default value `-1` indicates that the JVM default value
should be used. A value of `0` means there is no limit.
wrap:: _(Optional)_ If `true`, the returned `SSLEngine`, `SSLSocket`, and `SSLServerSocket` instances will be wrapped to
protect against further modification. The default value is `false`.
pre-realm-principal-transformer:: _(Optional)_ A principal transformer to apply before the realm is selected.
post-realm-principal-transformer:: _(Optional)_ A principal transformer to apply after the realm is selected.
final-principal-transformer:: _(Optional)_ A final principal transformer to apply for this mechanism realm.
realm-mapper:: _(Optional)_ The realm mapper to be used for SSL authentication.

[[configuring-a-client-sslcontext]]
=== Configuring a client SSLContext

Using the Elytron subsystem, it is possible to configure an `SSLContext` for use on the client side of a connection.

Adding a client `SSLContext` takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/client-ssl-context=test-client-ssl-context:add(...)
----

The following attributes can be specified when creating a `client-ssl-context`:

key-manager:: _(Optional)_ A reference to the `KeyManager` to be used by this `SSLContext`.
trust-manager:: _(Optional)_ A reference to the `TrustManager` to be used by this `SSLContext`.
cipher-suite-filter:: _(Optional)_ The filter to be applied to the cipher suites for TLSv1.2 and below made available
by this SSLContext. The format of this attribute is described in detail in
http://wildfly-security.github.io/wildfly-elytron/master/org/wildfly/security/ssl/CipherSuiteSelector.html#fromString-java.lang.String-[org.wildfly.security.ssl.CipherSuiteSelector.fromString(selector)].
The default value is `DEFAULT`, which corresponds to all known cipher suites that do not have NULL encryption and
excludes any cipher suites that have no authentication.
cipher-suite-names:: _(Optional)_ The enabled cipher suites for TLSv1.3. The format of this attribute is a simple colon
(":") separated list of TLSv1.3 cipher suite names (e.g., `TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256`).
This attribute must be specified in order for TLSv1.3 to be enabled.
protocols:: _(Optional)_ A space separated list of the protocols to be supported by this `SSLContext`. The default value
is `TLSv1 TLSv1.1 TLSv1.2 TLSv1.3`. Note that the TLSv1.3 protocol will only be usable when running against JDK 11 or higher.
provider-name:: _(Optional)_ The name of the provider to use. If not specified, all providers from `providers` will be
passed to the `SSLContext`.
providers:: _(Optional)_ The name of the providers to obtain the `Provider[]` to use to load the `SSLContext`.

*WARNING* It is possible to use TLSv1.3 with WildFly when running against JDK 11 or higher. However, if JDK 11
is in use and if there is a very large number of TLSv1.3 requests being made, it is possible that a drop in
performance (throughput and response time) will occur compared to TLSv1.2. Upgrading to newer JDK versions
should improve performance. For this reason, the use of TLSv1.3 is currently disabled by default. TLSv1.3 can
be enabled by configuring the new `cipher-suite-names` attribute in the SSL Context resource definition in the
Elytron subsystem as described in the previous two sections. It is recommended to test for performance
degradation prior to enabling TLSv1.3 in a production environment. See https://issues.redhat.com/browse/WFWIP-160[WFWIP-160]
for more details.

*Note:* When using TLSv1.3, it is important to keep in mind that session IDs have become essentially obsolete.
This means that the session ID can no longer reliably be used to test if a session was resumed. Instead,
creation time can be used to test if a session was resumed. Currently, clients need to read from the server after
the first handshake in order to receive the `NewSessionTicket` that can be used for resumption. However, this may
change once https://bugs.openjdk.java.net/browse/JDK-8209953[JDK-8209953] is resolved.


=== Default SSLContext

Many libraries that can be used within deployments may require SSL configuration for any connections they establish, these libraries tend to be configurable by the caller or if no configuration is provided fall back to using the default `SSLContext` for the process available from: -

[source,java,options="nowrap"]
----
javax.net.ssl.SSLContext.getDefault();
----

By default this `SSLContext` is configured using system properties, however within the WildFly Elytron subsystem it is possible to specify that one of the configured contexts should be associated and used as the default.

To make use of this feature configure your `SSLContext` as normal, the following command can then be used to specify which `SSLContext` should be used as the default.

[source,options="nowrap"]
----
/subsystem=elytron:write-attribute(name=default-ssl-context, value=client-context)
----

As existing services and deployments could have cached the default `SSLContext` prior to this being set a reload is required to ensure the default gets set before the deployments are activated.

[source,options="nowrap"]
----
:reload
----

*Note:* If the `default-ssl-context` attribute is subsequently 'undefined' the standard APIs do not provide us with a mechanism to revert the default so in this situation the Java process would need be restarted.

[source,options="nowrap"]
----
/subsystem=elytron:undefine-attribute(name=default-ssl-context)
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-restart" => true,
        "process-state" => "restart-required"
    }
}
----

=== Configuring SNI

Using the WildFly Elytron subsystem it is possible to configure an SSL context which supports SNI.  By supporting SNI if an SNI host name is available whilst the SSLSession is being negotiated a host specific SSLContext will be selected.  If no host specific SSLContext is identified either because no host name was received or because there is no match a default SSLContext will be used instead.  By identifying a host specific SSLContext it means that a certificate appropriate for that host can be used.

The following command demonstrates how an SNI aware SSLContext can be added: - 

[source,options="nowrap"]
----
[standalone@localhost:9990 /] ./subsystem=elytron/server-ssl-sni-context=test-sni:add(default-ssl-context=jboss,host-context-map={localhost=localhost, wildfly.org=wildfly})
{"outcome" => "success"}
----

This example assumes that three SSLContexts have been previously defined following the steps available previously in this document, those contexts are `jboss`, `localhost`, and `wildfly`.

During negotiation of the SSLSession if the SNI host name received is `localhost` then the `localhost` SSLContext will be used, if the SNI host name is `wildfly.org` then the `wildfly` SSLContext will be used.  If no SNI host name is received or if we receive a name that does not match this will fallback and use the `jboss` SSLContext.

The resulting resource looks like: -

[source,options="nowrap"]
----
[standalone@localhost:9990 /] ./subsystem=elytron/server-ssl-sni-context=test-sni:read-resource
{
    "outcome" => "success",
    "result" => {
        "default-ssl-context" => "jboss",
        "host-context-map" => {
            "localhost" => "localhost",
            "wildfly.org" => "wildfly"
        }
    }
}
----

Within the `host-context-map` it is also possible to define wildcard mappings such as `&#42;` and `&#42;.wildfly.org`.

[[configuring-the-elytron-and-security-subsystems]]
== Configuring the Elytron and Security Subsystems

[[enable-and-disable-the-elytron-subsystem]]
=== Enable and Disable the Elytron Subsystem

[[to-add-the-elytron-extension-required-for-the-elytron-subsystem]]
==== To add the elytron extension required for the elytron subsystem:

[source,options="nowrap"]
----
/extension=org.wildfly.extension.elytron:add()
----

[[to-enable-the-elytron-subsystem-in-wildfly]]
==== To enable the Elytron subsystem in WildFly:

[source,options="nowrap"]
----
/subsystem=elytron:add
 
reload
----

[[to-disable-the-elytron-subsystem-in-wildfly]]
==== To disable the Elytron subsystem in WildFly:

[source,options="nowrap"]
----
/subsystem=elytron:remove
 
reload
----

*IMPORTANT:* Other subsystems within WildFly may have dependencies on
the _elytron_ subsystem. If these dependencies are not resolved before
disabling it, you will see errors when starting WildFly.

[[enable-and-disable-the-security-subsystem]]
=== Enable and Disable the Security Subsystem

[[to-disable-the-security-subsystem-in-wildfly]]
==== To disable the security subsystem in WildFly:

[source,options="nowrap"]
----
/subsystem=security:remove
 
reload
----

*IMPORTANT:* Other subsystems within WildFly may have dependencies on
the _security_ subsystem. If these dependencies are not resolved before
disabling it, you will see errors when starting WildFly.

[[to-enable-the-security-subsystem-in-wildfly]]
==== To enable the security subsystem in WildFly:

[source,options="nowrap"]
----
/subsystem=security:add
 
reload
----

[[use-the-elytron-and-security-subsystems-in-parallel]]
=== Use the Elytron and Security Subsystems in Parallel

By default the _elytron_ and _security_ subsystems will run in parallel
if both are enabled. For authentication in applications, you can use the
_application-security-domain_ property in the _undertow_ subsystem to
configure a security domain in the _elytron_ subsystem.

[source,options="nowrap"]
----
/subsystem=undertow/application-security-domain=exampleApplicationDomain:add(http-authentication-factory=example-http-auth)
----

*NOTE:* This must match the _security-domain_ configured in the
_jboss-web.xml_ of your application.

If the _application-security-domain_ is not set, WildFly will look for a
security domain configured in the _security_ subsystem that matches the
_security-domain_ configured in the _jboss-web.xml_ of your application.

For enabling HTTPS using a legacy security realm, you can use the
_security-realm_ attribute in the _https-listener_ section of the
_undertow_ subsystem:

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

For enabling HTTPS using _elytron_, you need to undefine the
_security-realm_ attribute and set the _ssl-context_ attribute. As there
has to be always configured either _ssl-context_ or _security-realm_ you
have to use batch operation when changing between those:

[source,options="nowrap"]
----
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=httpsSSC)
run-batch
----

[[creating-elytron-subsystem-components]]
== Creating Elytron Subsystem Components

[[create-an-elytron-security-realm]]
=== Create an Elytron Security Realm

Security realms in the Elytron subsystem, when used in conjunction with
security domains, are use for both core management authentication as
well as for authentication with applications. Security realms are also
specifically typed based on their identity store, for example
_jdbc-realm_, _filesystem-realm_, _properties-realm_, etc.

Adding a security realm takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/type-of-realm=realmName:add(....)
----

Examples of adding specific realms, such as _jdbc-realm_,
_filesystem-realm_, and _properties-realm_ can be found in previous
sections.

[[create-an-elytron-role-decoder]]
=== Create an Elytron Role Decoder

A role decoder converts attributes from the identity provided by the
security realm into roles. Role decoders are also specifically typed
based on their functionality, for example _empty-role-decoder_,
_simple-role-decoder_, _custom-role-decoder_, and _aggregate-role-decoder_.

Adding a role decoder takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/ROLE-DECODER-TYPE=roleDeoderName:add(....)
----

==== Create an Elytron Role Decoder that makes use of the IP Address of the Remote Client

A role decoder that is configured on a security realm assigns roles to
an identity based on attributes provided by the security realm. It is
also possible to configure a role decoder that makes use of the IP
address of the remote client when determining the roles associated
with an identity. As an example, we might want to make use of the IP
address of the remote client in order to assign a user a particular
role when establishing a connection to the server from a corporate
network and a different role when establishing a connection to the
server from a different network.

Adding a role decoder that makes use of the remote client's IP
address takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/source-address-role-decoder=roleDecoderName:add(source-address="...", pattern="...", roles=[...])
----

In particular, a _source-address-role-decoder_ has the following attributes:

* _source-address_ - The IP address of the remote client.

* _pattern_ - A regular expression that specifies the IP address to match.

* _roles_ - The list of roles to assign if the source IP address matches the given address.

Only one of _source-address_ and _pattern_ should be specified.

For example, the following _source-address-role-decoder_ could be configured to specify
that a user should be assigned the "Administrator" role when establishing a connection
to the server from the 10.10.10.10 IP address:

[source,options="nowrap"]
----
/subsystem=elytron/source-address-role-decoder=decoder1:add(source-address="10.10.10.10", roles=["Administrator"])
----

Once a _source-address-role-decoder_ has been configured, it can be referenced from a _security-domain_:

[source,options="nowrap"]
----
/subsystem=elytron/security-domain=exampleSD:add(..., role-decoder=decoder1)
----

It is also possible to assign permissions to an identity based on its roles using a
link:Using_the_Elytron_Subsystem{outfilesuffix}#create-an-elytron-permission-mapper[simple permission mapper].

Example configuration:

[source,options="nowrap"]
----
/subsystem=elytron/source-address-role-decoder=decoder1:add(source-address="10.10.10.10", roles=["Administrator"])
/subsystem=elytron/simple-permission-mapper=ipPermissionMapper:add(permission-mappings=[{roles=["Administrator"], permission-sets=[{permission-set=login-permission}]}])
/subsystem=elytron/security-domain=exampleSD:add(..., role-decoder=decoder1, permission-mapper=ipPermissionMapper)
----

The above example configures a security domain with a source address role decoder that
will assign the "Administrator" role when the IP address of the remote client matches
the configured address and a simple permission mapper that only assigns the
"LoginPermission" if the identity has the "Administrator" role. Thus, authentication
will succeed if the IP address of the remote client matches the configured address.

It is also possible to configure an _aggregate-role-decoder_. This consists of
two or more _role-decoder_ elements where each element is a reference to a configured
role decoder. Each role decoder will be applied and the returned value will be a union of
the roles returned by each decoder.

Example configuration:

[source,options="nowrap"]
----
/subsystem=elytron/source-address-role-decoder=decoder1:add(source-address="10.10.10.10", roles=["Administrator"])
/subsystem=elytron/source-address-role-decoder=decoder2:add(source-address="12.12.12.12", roles=["Users"])
/subsystem=elytron/aggregate-role-decoder=aggregateDecoder:add(role-decoders=[decoder1, decoder2])
----

[[create-an-elytron-permission-set]]
=== Create an Elytron Permission Set

Permission sets can be used to assign permissions to an identity.

Adding a permission set takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/permission-set=PermissionSetName:add(permissions=[{class-name="...", module="...", target-name="...", action="..."}...])
----

where _permissions_ consists of a set of permissions, where each permission has the following attributes:

* _class-name_ is the fully qualified class name of the permission. This is the only permission attribute that is required.

* _module_ is the optional module to use to load the permission.

* _target-name_ is the optional target name to pass to the permission as it is constructed.

* _action_ is the optional action to pass to the permission as it is constructed.

[[create-an-elytron-permission-mapper]]
=== Create an Elytron Permission Mapper

In addition to roles being assigned to a identity, permissions may also
be assigned. A permission mapper assigns permissions to an identity.
Permission mappers are also specifically typed based on their
functionality, for example _logical-permission-mapper_,
_simple-permission-mapper_, and _custom-permission-mapper_.

Adding a permission mapper takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/simple-permission-mapper=PermissionMapperName:add(...)
----

[[create-an-elytron-role-mapper]]
=== Create an Elytron Role Mapper

A role mapper maps roles after they have been decoded to other roles.
Examples include normalizing role names or adding and removing specific
roles from principals after they have been decoded. Role mappers are
also specifically typed based on their functionality, for example
_add-prefix-role-mapper_, _add-suffix-role-mapper_, and
_constant-role-mapper_.

Adding a role mapper takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/ROLEM-MAPPER-TYPE=roleMapperName:add(...)
----

[[create-an-elytron-security-domain]]
=== Create an Elytron Security Domain

Security domains in the Elytron subsystem, when used in conjunction with
security realms, are use for both core management authentication as well
as for authentication with applications.

Adding a security domain takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/security-domain=domainName:add(realms=[{realm=realmName,role-decoder=roleDecoderName}],default-realm=realmName,permission-mapper=permissionMapperName,role-mapper=roleMapperName,...)
----

[[create-an-elytron-authentication-factory]]
=== Create an Elytron Authentication Factory

An authentication factory is an authentication policy used for specific
authentication mechanisms. Authentication factories are specifically
based on the authentication mechanism, for example
_http-authentication-factory_ and +
_sasl-authentication-factory_ and _kerberos-security-factory_.

Adding an authentication factory takes the general form:

[source,options="nowrap"]
----
/subsystem=elytron/AUTH-FACTORY-TYPE=authFactoryName:add(....)
----

[[create-an-elytron-policy-provider]]
=== Create an Elytron Policy Provider

Elytron subsystem provides a specific resource definition that can be
used to configure a default ruby Policy provider. The subsystem allows
you to define multiple policy providers but select a single one as the
default:

[source,options="nowrap"]
----
/subsystem=elytron/policy=policy-provider-a:add(custom-policy=\[{name=policy-provider-a, class-name=MyPolicyProviderA, module=x.y.z}\])
----

[[create-an-elytron-case-principal-transformer]]
=== Create an Elytron Case Principal Transformer

Principal transformers can take a name and map it to another representation of the name or perform
some normalisation. A ``case-principal-transformer`` converts a principal to upper or lower case.
As an example, we might want to convert our principal to upper case if the identities in our realm
are stored in upper case.

Adding a ``case-principal-transformer`` that converts a principal to upper/lower case takes the
general form:

[source,options="nowrap]
----
/subsystem=elytron/case-principal-transformer=transformerName:add(upper-case="...")
----

In particular, a ``case-principal-transformer`` has the following attribute:

* ``upper-case`` - A boolean value to indicate whether the principal should be converted to upper case.
Indicating ``false`` for this attribute converts the principal to lower case.

For example, the following ``case-principal-transformer`` could be configured to specify that
a principal should be transformed to lower case:

[source,options="nowrap"]
----
/subsystem=elytron/case-principal-transformer=transformer1:add(upper-case="false")
----

On the other hand, a ``case-principal-transformer`` could be configured by omitting the
``upper-case`` attribute, which is then set to ``true`` by default:

[source,options="nowrap"]
----
/subsystem=elytron/case-principal-transformer=transformer2:add()
----

:leveloffset: +1

include::Subsystem_Component_Documentation.adoc[]

:leveloffset: -1
