Native Security Realm in GlassFish
- From the sandbox
- Tutorial
It's no secret that application servers exist in order to remove some of the work from the developer and assign it to ready-made mechanisms. In particular, the authentication mechanism in the Glassfish application server can be organized using the so-called Security Realms. There are several built-in options, such as authentication via DBMS, LDAP, PAM, Certificate and regular reading from a file. However, they may not suit us because of their limitations (LDAP, for example, can only work with one domain specified in advance). Therefore, we will consider the creation of our own security realm.
Custom security realm consists of at least two classes. One of which extends the AppservRealm class (com.sun.appserv.security.AppservRealm), and the second, respectively, AppservPasswordLoginModule (com.sun.appserv.security.AppservPasswordLoginModule). To get com.sun.appserv.security. * You need to import /glassfish/modules/security.jar as a library
In the realm class, it is necessary to redefine the methods for obtaining an authentication type (usually the name of realm) and obtaining user groups by their name - in this article we intentionally miss an overview of Java EE authorization.
Accordingly, here we can realize the flexibility of the mechanism in obtaining groups by user name, for example from a DBMS. This example uses one group that indicates that the user is authenticated. Property jaas-context is specified here to associate this class with the following.
In this class, you need to implement an authentication method. It consists of receiving and verifying the realm using it, verifying the correctness of the entered login and password (or other details), and finally, receiving and transmitting user groups.
We put the compiled classes (packages with the corresponding classes inside) into the <glassfish domain> / lib / classes directory.
We must also determine that our AppservPasswordLoginModule belongs to a specific context. You need to edit the file <glassfish domain> /config/login.conf adding a "link":
In which we define the context and refer to the need for a module.
Feel free to start / reboot our application server and open the administrator's GUI.
Create a new Security Realm. Now we do not need to select a class from the list, but introduce the full realm class: ru.khmb.security.Realm. Do not forget to specify the jaas-context option which associates our realm with the authentication module through the context specified in the login.conf file, i.e. in our case, jaas-context = KHMBRealm
Everything, now you can use Realm.
When implementing the mechanism, the source was a blog post .
Update 02/08/2013:
There is a good description of the creation of various Security Realms (security areas) in David Heffelfinger’s book “Java EE 6 and GlassFish 3 Application Server”
Custom security realm consists of at least two classes. One of which extends the AppservRealm class (com.sun.appserv.security.AppservRealm), and the second, respectively, AppservPasswordLoginModule (com.sun.appserv.security.AppservPasswordLoginModule). To get com.sun.appserv.security. * You need to import /glassfish/modules/security.jar as a library
package ru.khmb.security;
import com.sun.appserv.security.AppservRealm;
import com.sun.enterprise.security.auth.realm.BadRealmException;
import com.sun.enterprise.security.auth.realm.InvalidOperationException;
import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
import com.sun.enterprise.security.auth.realm.NoSuchUserException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
public class Realm extends AppservRealm {
private static final String PARAM_JAAS_CONTEXT = "jaas-context";
private static final String GROUP_ALL = "Authenticated";
@Override
public void init(Properties properties)
throws BadRealmException, NoSuchRealmException {
String propJaasContext = properties.getProperty(PARAM_JAAS_CONTEXT);
if (propJaasContext != null) {
setProperty(PARAM_JAAS_CONTEXT, propJaasContext);
}
}
@Override
public String getAuthType() {
return "KHMB Realm";
}
@Override
public Enumeration getGroupNames(String user)
throws InvalidOperationException, NoSuchUserException {
Vector vector = new Vector();
vector.add(GROUP_ALL);
return vector.elements();
}
}
In the realm class, it is necessary to redefine the methods for obtaining an authentication type (usually the name of realm) and obtaining user groups by their name - in this article we intentionally miss an overview of Java EE authorization.
Accordingly, here we can realize the flexibility of the mechanism in obtaining groups by user name, for example from a DBMS. This example uses one group that indicates that the user is authenticated. Property jaas-context is specified here to associate this class with the following.
package ru.khmb.security;
import com.sun.appserv.security.AppservPasswordLoginModule;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import javax.security.auth.login.LoginException;
public class LoginModule extends AppservPasswordLoginModule {
@Override
protected void authenticateUser() throws LoginException {
if (!(_currentRealm instanceof Realm)) {
throw new LoginException("Realm not KHMBRealm");
}
Realm realm = (Realm) _currentRealm;
authenticate(_username, _password);
Enumeration enumeration = null;
List authenticatedGroups = new LinkedList();
try {
enumeration = realm.getGroupNames(_username);
} catch (Exception e) {
throw new LoginException("Get groups exception");
}
for (int i = 0; enumeration != null && enumeration.hasMoreElements(); i++) {
authenticatedGroups.add((String) enumeration.nextElement());
}
commitUserAuthentication(authenticatedGroups.toArray(new String[0]));
}
private static void authenticate(String login, String password) throws LoginException {
try {
LDAP.authenticate(login, password);
} catch (Exception e) {
throw new LoginException("Authenticate exception:" + e.getMessage());
}
}
}
In this class, you need to implement an authentication method. It consists of receiving and verifying the realm using it, verifying the correctness of the entered login and password (or other details), and finally, receiving and transmitting user groups.
We put the compiled classes (packages with the corresponding classes inside) into the <glassfish domain> / lib / classes directory.
We must also determine that our AppservPasswordLoginModule belongs to a specific context. You need to edit the file <glassfish domain> /config/login.conf adding a "link":
KHMBRealm {
ru.khmb.security.LoginModule required;
};
In which we define the context and refer to the need for a module.
Feel free to start / reboot our application server and open the administrator's GUI.
Create a new Security Realm. Now we do not need to select a class from the list, but introduce the full realm class: ru.khmb.security.Realm. Do not forget to specify the jaas-context option which associates our realm with the authentication module through the context specified in the login.conf file, i.e. in our case, jaas-context = KHMBRealm
Everything, now you can use Realm.
When implementing the mechanism, the source was a blog post .
Update 02/08/2013:
There is a good description of the creation of various Security Realms (security areas) in David Heffelfinger’s book “Java EE 6 and GlassFish 3 Application Server”