[[Custom_Components]]
= Custom Components

ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]

WildFly Elytron subsystem allows adding custom implementation of different
components in form of WildFly modules into the WildFly instance and use them
by the same way as built-in Elytron subsystem components.
For example, you can create custom security event listener to develop custom
audit mechanisms and store information about user authentication attempts in
custom storage structure. Or you can create custom security realm to
authenticate users against your own identities storage.

To find what types of custom components you can implement you can use Tab
completion:

----
[standalone@localhost:9990 /] /subsystem=elytron/custom-
custom-credential-security-factory  custom-realm
custom-evidence-decoder             custom-realm-mapper
custom-modifiable-realm             custom-role-decoder
custom-permission-mapper            custom-role-mapper
custom-principal-decoder            custom-security-event-listener
custom-principal-transformer
----

== Security event listener

This section describes how to add a custom security event listener. Similar steps can be followed to add another
custom component type.

To create custom security event listener you need to implement `java.util.function.Consumer<org.wildfly.security.auth.server.event.SecurityEvent>` interface.
Resulting class needs to be packed into JAR and WildFly module created.
You can create appropriate directory structure and module descriptor manually, or you can use following command of WildFly CLI:

----
bin/jboss-cli.sh
module add --name=my.module --resources=my-listener.jar --dependencies=org.wildfly.security.elytron
----

Check
link:Developer_Guide.html#Class_Loading_in_WildFly[Class loading doc]
for more information how to create WildFly module.

When appropriate module is on place, you can start using it by adding Elytron subsystem resource:

----
/subsystem=elytron/custom-security-event-listener=myListener:add(
        module=my.module, class-name=my.module.MyAuditListener)
----

Now you can start to use it as any other security event listener - typically to set it as listener of `ApplicationDomain`:

----
/subsystem=elytron/security-domain=ApplicationDomain:write-attribute(name=security-event-listener, value=myListener)
----

After server reload the listener will receive all security events from given security domain.

== Configurable custom components

You can also provide some component configuration from the subsystem, if class of your component will implement following method:

----
public void initialize(Map<String, String> configuration)
----

Afterwards you can provide configuration into your component from the subsystem using attribute `configuration`:

----
/subsystem=elytron/custom-...=my-component:add(module=..., class-name=..., configuration={myAttribute="myValue"})
----

After the component construction, the `initialize` method will be called with the configuration.

