Glassfish allows creating a JDBC realm that authenticates users and retrieves their roles from a database.
T_USERS |
USERNAME (PK) |
PASSWORD |
T_GROUPS |
USERNAME (FK) |
GROUPNAME |
This is fine if the tables do not exist, but what if the database already exists or you require a mapping table for the many-to-many relationship between users and groups? For example, as our application was using Spring Security we already had a database schema as follows:
T_USERS |
USERNAME (PK) |
PASSWORD |
.... |
T_USER_AUTHORITIES |
USERNAME (FK) |
ROLE_ID (FK) |
T_ROLES |
ROLE_ID (PK) |
ROLENAME |
In such a scenario, the Glassfish provided JDBCRealm is insufficient and a custom realm needs to be created. The custom jdbc realm will allow Glassfish to authenticate using the same database as the application is using to manage the users.
Creating a custom realm requires providing a custom JAAS login module class and custom realm class.
Note the export-package element should contain the name of the packages of the custom LoginModule class and custom AppservRealm classes.
Once the OSGI bundle has been created it can be loaded by copying it to <GF_HOME>/domains/<DOMAIN-NAME>/autodeploy/bundles.
The realm can now be created from the Glassfish administrative console. When an application that utilizes this realm is accessed the LoginModule will be initialized.
Creating a custom realm requires providing a custom JAAS login module class and custom realm class.
- The custom login module must extend com.sun.appserv.security.AppservPasswordLoginModule.This class implements the javax.security.auth.spi.LoginModule.
- The custom realm class must extend the abstract com.sun.appserv.security.AppservRealm class. You may find it easier to view the source code of the com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm class to provide a base from which to develop the custom realm class. Unfortunately, the JDBCRealm class is final and so cannot be extended. The realm class must also contain the HK2 @Service annotation to allow integration with the Glassfish OSGI module system.
- Update the <GF_HOME>/domains/<DOMAIN-NAME>/config/login.conf to add an entry for the custom realm referring to the custom LoginModule.
- Finally there should be a file named javax.security.auth.spi.LoginModule in the META-INF/services directory with the fully qualified name of the LoginModule class.
maven-bundle-plugin
<dependencies>
<dependency>
<groupId>org.glassfish.security</groupId>
<artifactId>security</artifactId>
<version>3.1.1-b11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package> ${project.groupId}.glassfish.auth;version=${project.version}
</Export-Package>
<Import-Package>
java.util,
javax.security.auth,
javax.security.auth.login,
javax.sql,
org.glassfish.security.common,
org.jvnet.hk2.annotations,
org.jvnet.hk2.component,
com.sun.appserv.connectors.internal.api,
com.sun.appserv.security,
com.sun.enterprise.security.common,
com.sun.enterprise.util,
com.sun.enterprise.util.i18n,
com.sun.enterprise.security.auth.realm,
com.sun.enterprise.security.auth.realm.jdbc,
com.sun.enterprise.security.auth.login.common,
com.sun.enterprise.security.auth.digest.api,
com.sun.enterprise.universal
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
Once the OSGI bundle has been created it can be loaded by copying it to <GF_HOME>/domains/<DOMAIN-NAME>/autodeploy/bundles.
The realm can now be created from the Glassfish administrative console. When an application that utilizes this realm is accessed the LoginModule will be initialized.