Writing a Custom Authentication Data Publisher for WSO2 IS 5.8.0
Analyzing login statistics is very crucial when it comes to the security of systems and applications. Analytics will help you in fraud and anomaly detection so that you can possibly block the transactions, lock the user accounts or generate alerts to the responsible parties.
WSO2 Identity Server has this analytics feature. You can use WSO2 IS Analytics or any other analytics server that you like. WSO2 Identity Server is implemented with the great extensibility that you can plug-in any external analytics server, gather authentication data and perform the analytics.
WSO2 Identity Server published information login related and session related information. Up to WSO2 Identity Server version 5.7.0, data publishers were extended from AbstractAuthenticationDataPublisher and invoked iteratively by the AuthnDataPublisherProxy when there is an event triggered, such that these data publishers send events to their corresponding destinations.
From WSO2 IS 5.8.0 onwards, these data publishers are implemented to act as event handlers that subscribe to authentication events. So according to this design approach,
- When a session is changed, the identity-framework publishes an event to the AuthnDataPublisherProxy.
- AuthnDataPublisherProxy uses the IdentityEventService in identity-framework to invoke corresponding handlers to handle the event.
- These event handlers extend the AbstractEventHandler and override its handleEvent method.
When the event publisher triggers an event, there is a dedicated service that will transfer this event from the Identity Server to the analytics server. This service is handled by the Event Adapters. They facilitate maintaining connections between the data source and the data sink. They are several output event adapters supported by the WSO2 products.
Now you know the basics of publishing events of the WSO2 Identity Server.
Before going through the implementation details of the custom event publisher, let me explain the scenario that we are going to achieve, using an example.
Assume that we have users accessing the Dashboard application. We need to gather information about these users and whether they could authenticate to the application successfully. We will require the details such as authentication type, authentication result, username, userstore domain, tenant domain, application name and authenticator details. And we are collecting that information in a sample external server called, http://webhook.site. The identity server and webhook site will communicate over HTTP.
Let’s see how you can write your own event publisher to publish events to your external server.
This customization will basically contain 4 steps.
Step 1: Configuring the event stream
Step 2: Configuring the event adapter
Step 3: Implementing the event publisher
Step 4: Registering the event publisher in the WSO2 Identity Server
Let’s go through each of these steps in detail.
Step 1: Configuring the event stream
Events process data and interact with external systems. Event is a unit of data, and an event stream is a sequence of events of a particular type. The type of events can be defined as an event stream definition. Definitions of the event streams are stored in the filesystem as deployable artifacts in the <IS_HOME>/repository/deployment/server/eventstreams/ directory as .json files. These are hot deployable files and can be added/removed when the server is up and running.
Let’s name our custom event stream as, org.wso2.is.analytics.stream.CustomAuthData:1.0.0
- Create a new file with the name
org.wso2.is.analytics.stream.CustomAuthData:1.0.0
inside <IS_HOME>/repository/deployment/server/eventstreams/ folder. - Define the stream as follows. You can find the complete definition here[1].
Step 2: Configuring the event adapter
In this example, we will use the HTTP event adapter which sends events to a specific Web service location using POST.
- Create an XML file inside <IS_HOME>/repository/deployment/server/eventpublishers.
- Add the following configuration details. You can find the complete file here.
You can give the URL of your analytics server as the http.url and the events coming to the stream org.wso2.is.analytics.stream.CustomAuthData is published from this.
Step 3: Implementing the event publisher
The custom event publisher is written as an OSGi service and deployed in the Identity Server.
- Create a folder structure as below.
- SampleEventPublisherServiceComponent: Register the publisher as an OSGi service and register other required services
- SampleEventPublisherDataHolder: Hold the required services
- SampleEventPublisher: The implementation of the publisher. This class extends the AbstractEventHandler class
You can refer to the pom.xml file for the project from the sample given. This has the dependencies relevant to the WSO2 IS 5.8.0. I have attached the complete source code for your reference and check the inline comments for more details.[3]
In the SampleEventPublisherServiceComponent class, you need to add the method to activate the OSGi bundle and another method to register the EventStreamService which will be responsible for publishing the event.
SampleEventPublisher handles the stream publishing part. I will briefly describe the functions that are in the sample so that you can customize the places you want.
handleEvent(Event event)
You must override this method to handle the event as required.getName()
You must override this method and return the name of your event handler.isCustomLoginDataPublishingEnabled()
This method will check whether the event handler is enabled from theidentity-event.properties
file in the <IS_HOME>/repository/conf/identity directory. The relevant config is “customLoginDataPublisher.enable”createPayload(AuthenticationData authenticationData)
This method populates and returns an array of objects with the required attributes. This array is considered as the payload of the event.publishToAnalytics(AuthenticationData authenticationData, Object[] payloadData)
This method consumes the event payload and adds it to the event stream that is configured in step 1.
When the implementation is done, go to the project home(sample-event-publisher) and run the command,
mvn clean install
When the compilation completes, you can find the org.wso2.event.publisher.sample-1.0.0.jar inside the sample-event-publisher/target
Step 4: Registering the event publisher in the WSO2 Identity Server
- Copy the org.wso2.event.publisher.sample-1.0.0.jar file to <IS_HOME>/repository/components/dropins folder.
- Enable the listener, org.wso2.carbon.identity.data.publisher.application.authentication.AuthnDataPublisherProxy from
identity.xml
file in the <IS_HOME>/repository/conf/identity directory.
3. Enable the custom event handler, org.wso2.event.publisher.sampleSampleEventPublisher from theidentity-event.properties
file in the <IS_HOME>/repository/conf/identity directory and subscribe to the events that you want to listen.
Now your custom event publisher is in action. Try out an authentication scenario using https://localhost:9443/dashboard. Then you can see there’s a POST request going to webhook site with the event details in the body.
In this way, you can customize and publish any data you want to any where you want when an authentication happens.