LoginListener
The LoginListener interface is a well-defined extension point provided by WSO2 Carbon. This provides an API that allows you to register a logic that should be executed when a user logs in. The onLogin() method will be invoked during a successful login and all your preferred actions should be defined within the implementation.
 WSO2 provides an API called LoginSubscriptionManagerService, which allows Login Listeners to subscribe to it. During a successful login session of a user, the LoginSubscriptionManagerService implementation calls the onLogin() function of all its subscribers.
The onLogin() method requires two parameters to be passed:
- configRegistry: Provides access to registry resource properties and allows registry operations. Examples: accessing the metadata of the resource at a given path, creating a resource by fetching the resource content from the given URL, renaming a resource in the registry, moving a resource in the registry, copying a resource in the registry etc. Â
- LoginEvent: Allows you to access data related to the logged in user (Example: username, tenantID, tenant domain).
Using the basic model explained above, you can implement the login functionality for your requirement. AÂ sample implementation of an OSGi bundle that implements the LoginListener API is given below.
Implementing LoginListener API
In this implementation, you are logging a message with the following details: username, tenantID and tenant domain of the user logged in to the management console of your Carbon product. The LoginSubscriptionManagerService interface allows components to subscribe a callback that can be called when a user login happens. The LogMessageListener interface is the implementation that I am using to implement the LoginListener interface. In the following, the onLogin() method is implemented and event data from LoginEvent is used for the log message.Â
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.core.services.callback.LoginListener; import org.wso2.carbon.core.services.callback.LoginEvent; import org.wso2.carbon.registry.core.Registry; /** * Implementing Login-Listener from core.services. */ public class LogMessageListener implements LoginListener { private static final Log log = LogFactory.getLog(LogMessageListener.class); public void onLogin(Registry configRegistry, LoginEvent event) { LoginEvent loginEvent = event; log.info("Logged in user : " + loginEvent.getUsername() + " with tenant ID " + loginEvent.getTenantId() + " with tenant domain : " + loginEvent.getTenantDomain()); //this registry variable contains APIs which control // tags/comments/ratings/versions/etc. Registry registry = configRegistry; } }
The LogMessageServiceComponent class is an OSGi service component that is used for subscribing to LoginListener. The activate() method does not include any major logic. The LoginSubscriptionManagerService class is used as a reference and the set-unset methods are added accordingly. A new instance of LoginListener is implemented, which subscribes to the LoginSubscriptionManagerService in the setLoginSubscriptionManagerService() method.
loginManager.subscribe(new LogMessageListner());
This allows you to subscribe the LogMessageListner() to LoginSubscriptionManagerService during bundle activation time.
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.*; import org.wso2.carbon.core.services.callback.LoginSubscriptionManagerService; import org.wso2.carbon.login.sample.listener.LogMessageListner; @Component(name = "sample.core.services.logcomponent", immediate = true) public class LogMessageServiceComponent { private static Log log = LogFactory.getLog(LogMessageServiceComponent.class); private static BundleContext bundleContext; @Activate protected void activate(ComponentContext context) { bundleContext = context.getBundleContext(); } @Reference( name = "login.subscription.service", service = org.wso2.carbon.core.services.callback.LoginSubscriptionManagerService.class, cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC, unbind = "unsetLoginSubscriptionManagerService" ) protected void setLoginSubscriptionManagerService(LoginSubscriptionManagerService loginManager) { log.debug("******* LoginSubscriptionManagerServic is set ******* "); loginManager.subscribe(new LogMessageListner()); } protected void unsetLoginSubscriptionManagerService(LoginSubscriptionManagerService loginManager) { log.debug("******* LoginSubscriptionManagerServic is unset ******* "); } protected void deactivate(ComponentContext ctxt) { LogMessageServiceComponent.bundleContext = null; log.debug("Carbon Core Services bundle is deactivated "); } }
Shown below is the pom.xml of the OSGi bundle. I have added a bundle activator class, which does not perform any complex logic. Please find the required maven dependencies given below.
 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.wso2.carbon</groupId> <artifactId>org.wso2.carbon.login.sample</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>bundle</packaging> <name>WSO2 Carbon - Samples</name> <url>http://wso2.org</url> <pluginRepositories> <pluginRepository> <id>wso2-nexus</id> <name>WSO2 internal Repository</name> <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url> <releases> <enabled>true</enabled> <updatePolicy>daily</updatePolicy> <checksumPolicy>ignore</checksumPolicy> </releases> </pluginRepository> </pluginRepositories> <dependencies> ... <dependency> <groupId>org.wso2.carbon</groupId> <artifactId>org.wso2.carbon.core.services</artifactId> <version>${core.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-scr-plugin</artifactId> <executions> <execution> <id>generate-scr-scrdescriptor</id> <goals> <goal>scr</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Bundle-Vendor>WSO2 Inc</Bundle-Vendor> <Bundle-SymbolicName>org.wso2.carbon.login.sample</Bundle-SymbolicName> <Bundle-Name>org.wso2.carbon.login.sample</Bundle-Name> <Private-Package>org.wso2.carbon.login.sample.internal</Private-Package> <Bundle-Version>1.0.0</Bundle-Version> <Bundle-Activator>org.wso2.carbon.login.sample.activator.LoginBundleActivator</Bundle-Activator> <Import-Package> org.osgi.framework, org.wso2.carbon.core.services.callback.*, *;resolution:=optional </Import-Package> <Export-Package>org.wso2.carbon.login.sample.activator*, org.wso2.carbon.login.sample.listener.* </Export-Package> <DynamicImport-Package>*</DynamicImport-Package> </instructions> </configuration> </plugin> </plugins> </build> </project>
After building the sample above, you can add your OSGi bundle to the <PRODUCT_HOME>/repository/components/dropins
 directory and start the Carbon server. Try logging in to the management console and you should see a log message as follows:
INFO {org.wso2.carbon.login.sample.listener.LogMessageListner} - Â Logged in user : admin with tenant ID -1234 with tenant domain : carbon.super
You can write your own custom logic that need to be invoked when a user login happens.