Sun Java Solaris Communities My SDN Account Join SDN
 
Article

Authentication Using Custom Realms in Sun Java System Application Server

 
By Harpreet Singh and Jagadesh Babu Munta, updated October, 2006  

Sun Java System Application Server uses a realm to provide authentication service. A realm is analogous to a security domain.

Sun Java System Application Server provides four types of realms that can be used by the container to authenticate against:

  • FileRealm – stores user information in a file database

  • Certificate Realm – stores user information in a certificate database

  • LDAP Realm – stores user information in an LDAP database

  • Solaris Realm – authenticates against the Solaris Operating System user database

Click here to learn more about these realms and how to configure them.

Sun Java System Application Server provides custom realms, a way for users to plug in their own authentication mechanisms. A custom realm can be used to authenticate against any user-specific security domain (for example, a database).

 
How to Implement a Custom Realm
Implementation involves the following three steps:

  1. Implement a Java Authentication and Authorization Service (JAAS) LoginModule

  2. Implement a Realm class

  3. Configure the Realm and LoginModule into the server

 
Implement a JAAS LoginModule

Sun Java System Application Server uses JAAS as the underlying authentication mechanism. Implementation procedures differ depending on the version of the application server.

Version 8.1 and Above:

In Sun Java System Application Server, version 8.1 and above (including version 9.x), custom realms must extend the com.sun.appserv.security.AppservPasswordLoginModule class. This class extends javax.security.auth.spi.LoginModule. Custom realms must not extend the JAAS LoginModule directly.

Custom login modules must provide an implementation for one abstract method defined in AppServPasswordLoginModule, as follows:

abstract protected void authenticateUser() throws LoginException

This method performs the actual authentication. The custom login module must not implement any of the other methods, such as login(), logout(), abort(), commit(), or initialize(). Default implementations are provided in AppservPasswordLoginModule, which hook into the Java System Application Server infrastructure.

The custom login module can access the following protected object fields, which it inherits from AppservPasswordLoginModule. These contain the user name and password of the user to be authenticated:

protected String _username;
protected String _password;

The authenticateUser() method must end with the following sequence:

String[] grpList;
....
/*
* Call the commitAuthentication to populate grpList with the set of groups to which
* _username belongs in this realm. */ return commitUserAuthentication(grpList);

The grpList argument is the list of groups to which the user belongs.

Version 8.0:

In Sun Java System Application Server, version 8.0, custom realms must extend the com.sun.enterprise.security.auth.login.PasswordLoginModule class. This class extends javax.security.auth.spi.LoginModule. Custom realms must not extend the JAAS LoginModule directly. 

Custom login modules must provide an implementation for one abstract method defined in PasswordLoginModule:

abstract protected void authenticate() throws LoginException

This method performs the actual authentication. The custom login module must not implement any of the other methods, such as login(), logout(), abort(), commit(), or initialize(). Default implementations are provided in PasswordLoginModule, which hook into the Java System Application Server infrastructure.

The custom login module can access the following protected object fields, which it inherits from PasswordLoginModule. These contain the user name and password of the user to be authenticated:

protected String _username;   
protected String _password;

The authenticate() method must end with the following sequence:

String[] grpList;
....
/*
 * Call the commitAuthentication to populate grpList with the set of groups to which
 * _username belongs in this realm.
 */
return commitAuthentication(_username, _password, _currentRealm, grpList);

The grpList argument is the list of groups to which the user belongs.

 
Implement a Realm Class

The Realm class is used to hook the custom realm into the Application Server. Typically, the authenticate method in the LoginModule calls into the realm implementation class to perform authentication.

Version 8.1 and Above

In Sun Java System Application Server, version 8.1 and above (including version 9.x), the realm implementation is available through the AppservPasswordLoginModule.

Custom realms must implement a Realm class that extends the com.sun.appserv.security.AppservRealm class to be bootstrapped into the Application Server.

Custom realms must implement the Properties() and getAuthType() methods:

public void init (Properties props) throws BadRealmException, NoSuchRealmException

The Properties() method is invoked during server startup when the realm is initially loaded. The props argument contains the properties defined for this realm in domain.xml. The realm can do any initialization it needs in this method. If the method returns without throwing an exception, Sun Java System Application Server identifies the realm as being ready to service authentication requests. If an exception is thrown, the realm is disabled.

public String getAuthType()

The getAuthType() method returns a realm-specific descriptive string representing the type of authentication done by this realm.

The realm can implement any other method in the AppservRealm class.

Version 8.0:

In Sun Java System Application Server, version 8.0, the realm implementation is available through the PasswordLoginModule.

Custom realms must implement a Realm class that extends the com.sun.enterprise.security.auth.realm.IASRealm class to be bootstrapped into the Application Server.

Custom realms must implement the Properties() and getAuthType() methods:

public void init (Properties props) throws BadRealmException, NoSuchRealmException

The Properties() method is invoked during server startup when the realm is initially loaded. The props argument contains the properties defined for this realm in domain.xml. The realm can do any initialization it needs in this method. If the method returns without throwing an exception, Sun Java System Application Server identifies the realm as being ready to service authentication requests. If an exception is thrown, the realm is disabled.

public String getAuthType()

The getAuthType() method returns a realm-specific descriptive string representing the type of authentication done by this realm.

The realm can implement any other method in the IASRealm class.

 
Sample Code

The sample code illustrates a very simple in-memory custom realm. Your custom realm will of course be much more complicated than this.

Version 8.1 and Above

/*
* SimpleCustomLoginModule.java
*
* Implementation of JAAS LoginModule as part of custom realm.
*
*
*/

package samples.security.customrealm.appserv;

import com.sun.appserv.security.AppservPasswordLoginModule;
import com.sun.enterprise.security.auth.realm.AuthenticationHandler;
import com.sun.enterprise.security.auth.realm.InvalidOperationException;
import javax.security.auth.login.LoginException;
import java.util.logging.Logger;
import java.util.logging.Level;
import com.sun.logging.LogDomains;

public class SimpleCustomLoginModule extends AppservPasswordLoginModule {
private static Logger _logger=null;
static{
_logger=LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
}
/*
* Custom realm implementation:only the following * method need to be implemented.
*
*/

protected void authenticateUser()
throws LoginException{

log("CustomRealm Auth Info:_username:"+_username+"; _password:"+_password+";_currentrealm:
"+_currentRealm);

// Get the current realm and check whether it is instance of your realm
if (!(_currentRealm instanceof SimpleCustomRealm)) {
throw new LoginException("customrealm:badrealm");
}
SimpleCustomRealm myCustomRealm = (SimpleCustomRealm)_currentRealm;

String[] grpList = myCustomRealm.authenticateUser(_username, _password);

if (grpList == null) { // JAAS behavior
throw new LoginException("customrealm:Login Failed with user " +_username);
}

log("login succeeded for " + _username);

// Add the code related to authenticating to your user database.
String[] groupListToForward = (String[])grpList.clone();

/*
* Call the commitAuthentication to populate * grpList with the set of groups to which
* _username belongs in this realm.
*/

/* commitUserAuthentication(_username, _password,
_currentRealm, groupListToForward);
*/
commitUserAuthentication(groupListToForward);

}


/*
* Helper methods.
*
* Simple message print method used throught the program
*/
public void log(String mesg){
_logger.log(Level.INFO, "SimpleCustomRealm:"+mesg );

}

}


/*
* SimpleCustomRealm.java
*
* Implementation of Custom Realm with in-memory users/groups
*
*
*/

package samples.security.customrealm.appserv;

import com.sun.appserv.security.AppservRealm;
import com.sun.enterprise.security.auth.realm.User;
import com.sun.enterprise.security.auth.realm.BadRealmException;
import com.sun.enterprise.security.auth.realm.NoSuchUserException;
import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
import com.sun.enterprise.security.auth.realm.AuthenticationHandler;
import com.sun.enterprise.security.auth.realm.InvalidOperationException;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.logging.Logger;
import java.util.logging.Level;
import com.sun.logging.LogDomains;

public class SimpleCustomRealm extends AppservRealm{

/* Assumed in memory users(usually this is not required and * should be loaded from
* LDAP/database/anyother user db.
* Format taken as username, password, groups separated by comma
*/
private static String AUTH_TYPE = "simplecustom";
private static String AUTH_TYPE_PARAM = "auth-type";
private String authType = null;
private String[][] eUsers = {
{"sjsuser","j2ee","users"},
{"sjsadmin","jes","admin"},
{"sjsdeployer","jes","users,admin"}
}; // predefined logins
private Hashtable usrpwdCache = null; // store user&password
private Hashtable groupCache = null; // store user&group
private Vector userDB = new Vector();
private Vector users = new Vector();
private Vector groups=new Vector();

private static Logger _logger=null;
static{
_logger=LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
}

/*
* This method is invoked during server startup when the realm is * initially loaded.
* The props argument contains the properties defined * for this realm in domain.xml.
* The realm can do any initialization it needs in this method.
* If the method returns without throwing an exception, * J2EE Application Server assumes the realm is ready * to service authentication requests. * If an exception is thrown, the realm is disabled, * check the server.log for messages.
*/
public void init(Properties props)
throws BadRealmException, NoSuchRealmException{

super.init(props);
log("init()...");



/*
* Set the jaas context, otherwise server doesn't indentify the login module.
* jaas-context is the property specified in domain.xml and * is the name corresponding to LoginModule
* config/login.conf
*/
String jaasCtx = props.getProperty(AppservRealm.JAAS_CONTEXT_PARAM);
this.setProperty(AppservRealm.JAAS_CONTEXT_PARAM, jaasCtx);

/*
* Get any other interested properties from configuration file - domain.xml
* say auth-type defined in domain.xml.
*/
String authTypeProp = props.getProperty(AUTH_TYPE_PARAM);
if (authTypeProp!=null){
this.authType = authTypeProp;
}else{
this.authType = AUTH_TYPE;
}

// Load the users from in memory.
loadUsers();

}

/**
* Load the users from into cache
*/
private void loadUsers(){
usrpwdCache = new Hashtable();
groupCache = new Hashtable();
// Put code here for loading the user database.
for(int i=0;i<3;i++){
String user= eUsers[i][0];
String pwd = eUsers[i][1];
String grp = eUsers[i][2];
log(i+".user="+user+";pwd:"+pwd+";grp="+grp);
usrpwdCache.put(user,pwd);
Vector grpV = new Vector();
StringTokenizer s = new StringTokenizer(grp,",");
while(s.hasMoreElements()){
grpV.add((String)s.nextToken());
}
groupCache.put(user,grpV);
}

}

/**
* Return a short description supported authentication by this realm.
*
* @return Description of the kind of authentication that is directly
* supported by this realm.
*/
public String getAuthType(){
return this.authType;
}


/**
* Returns names of all the users in this particular realm.
*
* @return enumeration of user names
*
*/
public Enumeration getUserNames() throws BadRealmException
{

return usrpwdCache.keys();
}


/**
* Returns the information recorded about a particular named user.
*
* This method always throws a BadRealmException since this method * is not supported in this context.
*
* @exception BadRealmException
*
*/
public User getUser(String name)
throws NoSuchUserException, BadRealmException
{
throw new BadRealmException("Not supported");
}

/**
* Returns names of all the groups in this particular realm.
*
* @return enumeration of group names (strings)
*
*/
public Enumeration getGroupNames()
throws BadRealmException
{
Vector groups = new Vector();
Enumeration users = groupCache.keys();
while (users.hasMoreElements()){
Vector group = (Vector)groupCache.get(users.nextElement());
Enumeration e = group.elements();
while(e.hasMoreElements()){
String gname=(String)e.nextElement();
if (!groups.contains(gname)){
groups.add(gname);
}
}
}
return groups.elements();
}

/**
* Returns enumeration of groups that a particular user belongs to.
*
*@exception NoSuchUserException
*/
public Enumeration getGroupNames(String user)
throws NoSuchUserException
{
Vector groupInfo = (Vector)groupCache.get(user);
if (groupInfo.isEmpty()){
log("No Such user "+user);
throw new NoSuchUserException("User not available. Check the username - " +user);
}
return groupInfo.elements();
}


/**
* Refreshes the realm data so that new users/groups are visible.
*
*/
public void refresh() throws BadRealmException
{
loadUsers();

}

/**
* Checks the authentication of a user and returns the groups it belongs to.
*
* @return groups that this particular user belongs to
*/
public String[] authenticateUser(String user, String password)
{
String[] groups = null;
String pwd = (String)usrpwdCache.get(user);
log("=>user="+user+";pwd="+pwd);

if(!usrpwdCache.containsKey(user)){
log("No Such User,"+user);
return null;
}

pwd = (String)usrpwdCache.get(user);
if (password.equals(pwd)){
Vector v = (Vector)groupCache.get(user);
Enumeration g = v.elements();
int index=0;
groups = new String[v.capacity()];
while(g.hasMoreElements()){
groups[index++]=(String)g.nextElement();
}
} else{
log("Login Failed for "+user+". Wrong Password!");
return null;
}

return groups;
}

/*
* Helper methods.
*
* Simple message print method used throught the program
*/
public void log(String mesg){
_logger.log(Level.INFO, "SimpleCustomRealm:"+mesg );
}

}

Version 8.0:

/*
* SimpleCustomLoginModule.java
*
* Implementation of JAAS LoginModule.
*
* Also See the note at * http://java.sun.com/j2ee/1.4/docs/devguide/dgsecure.html#wp25995
*
*/

package samples.security.customrealm;

import com.sun.enterprise.security.auth.login.PasswordLoginModule;
import com.sun.enterprise.security.auth.realm.AuthenticationHandler;
import com.sun.enterprise.security.auth.realm.InvalidOperationException;
import javax.security.auth.login.LoginException;
import java.util.logging.Logger;
import java.util.logging.Level;
import com.sun.logging.LogDomains;

public class SimpleCustomLoginModule extends PasswordLoginModule {
private static Logger _logger=null;
static{
_logger=LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
}
/*
* Custom realm implementation:only the following method need to be implemented.
* Obsolete method: * protected com.sun.enterprise.security.auth.AuthenticationStatus authenticate()
*
*/

protected void authenticate()
throws LoginException{

log("CustomRealm Auth Info:_username:"+_username+";
_password:"+_password+";
_currentrealm:" +_currentRealm);

// Get the current realm and check whether it is instance of your realm
if (!(_currentRealm instanceof SimpleCustomRealm)) {
throw new LoginException("customrealm:badrealm");
}
SimpleCustomRealm myCustomRealm = (SimpleCustomRealm)_currentRealm;

String[] grpList = myCustomRealm.authenticate(_username, _password);

if (grpList == null) { // JAAS behavior
throw new LoginException("customrealm:Login Failed with user " +_username);
}

log("login succeeded for " + _username);

// Add the code related to authenticating to your user database.
String[] groupListToForward = (String[])grpList.clone();

/*
* Call the commitAuthentication to populate grpList with the * set of groups to which _username belongs in this realm.
*/

commitAuthentication(_username, _password,
_currentRealm, groupListToForward);

}


/*
* Helper methods.
*
* Simple message print method used throught the program
*/
public void log(String mesg){
_logger.log(Level.INFO, "SimpleCustomRealm:"+mesg );

}

}

/*
* SimpleCustomRealm.java
*
* Implementation of Realm Class
*
*
*/

package samples.security.customrealm;

import com.sun.enterprise.security.auth.realm.IASRealm;
import com.sun.enterprise.security.auth.realm.User;
import com.sun.enterprise.security.auth.realm.BadRealmException;
import com.sun.enterprise.security.auth.realm.NoSuchUserException;
import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
import com.sun.enterprise.security.auth.realm.AuthenticationHandler;
import com.sun.enterprise.security.auth.realm.InvalidOperationException;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.logging.Logger;
import java.util.logging.Level;
import com.sun.logging.LogDomains;

public class SimpleCustomRealm extends com.sun.enterprise.security.auth.realm.IASRealm{

/* Assumed in memory users(usually this is not required and should be loaded from
LDAP/database/anyother user db.
Format taken as username, password, groups separated by comma
*/
private static String AUTH_TYPE = "simplecustom";
private static String AUTH_TYPE_PARAM = "auth-type";
private String authType = null;
private String[][] eUsers = {
{"sjsuser","j2ee","users"},
{"sjsadmin","jes","admin"},
{"sjsdeployer","jes","users,admin"}
}; // predefined logins
private Hashtable usrpwdCache = null; // store user&password
private Hashtable groupCache = null; // store user&group
private Vector userDB = new Vector();
private Vector users = new Vector();
private Vector groups=new Vector();

private static Logger _logger=null;
static{
_logger=LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
}

/*
* This method is invoked during server startup when the realm is initially loaded.
* The props argument contains the properties defined for this realm in domain.xml.
* The realm can do any initialization it needs in this method.
* If the method returns without throwing an exception, J2EE Application Server
* assumes the realm is ready to service authentication requests.
* If an exception is thrown, the realm is disabled. Check the server.log for messages.
*/
public void init(Properties props)
throws BadRealmException, NoSuchRealmException{

super.init(props);
log("init()...");



/*
* Set the jaas context, otherwise server doesn't indentify the login module.
* jaas-context is the property specified in domain.xml and is
* the name corresponding to LoginModule
* config/login.conf
*/
String jaasCtx = props.getProperty(IASRealm.JAAS_CONTEXT_PARAM);
this.setProperty(IASRealm.JAAS_CONTEXT_PARAM, jaasCtx);

/*
* Get any other interested properties from configuration file - domain.xml
* say auth-type defined in domain.xml.
*/
String authTypeProp = props.getProperty(AUTH_TYPE_PARAM);
if (authTypeProp!=null){
this.authType = authTypeProp;
}else{
this.authType = AUTH_TYPE;
}

// Load the users from in memory.
loadUsers();

}

/**
* Load the users from into cache
*/
private void loadUsers(){
usrpwdCache = new Hashtable();
groupCache = new Hashtable();
// Put code here for loading the user database.
for(int i=0;i<3;i++){
String user= eUsers[i][0];
String pwd = eUsers[i][1];
String grp = eUsers[i][2];
log(i+".user="+user+";pwd:"+pwd+";grp="+grp);
usrpwdCache.put(user,pwd);
Vector grpV = new Vector();
StringTokenizer s = new StringTokenizer(grp,",");
while(s.hasMoreElements()){
grpV.add((String)s.nextToken());
}
groupCache.put(user,grpV);
}

}

/**
* Return a short description supported authentication by this realm.
*
* @return Description of the kind of authentication that is directly
* supported by this realm.
*/
public String getAuthType(){
return this.authType;
}


/**
* Returns names of all the users in this particular realm.
*
* @return enumeration of user names
*
*/
public Enumeration getUserNames() throws BadRealmException
{

return usrpwdCache.keys();
}


/**
* Returns the information recorded about a particular named user.
*
* This method always throws a BadRealmException since this method * is not supported in this context.
*
* @exception BadRealmException
*
*/
public User getUser(String name)
throws NoSuchUserException, BadRealmException
{
throw new BadRealmException("Not supported");
}

/**
* Returns names of all the groups in this particular realm.
*
* @return enumeration of group names (strings)
*
*/
public Enumeration getGroupNames()
throws BadRealmException
{
Vector groups = new Vector();
Enumeration users = groupCache.keys();
while (users.hasMoreElements()){
Vector group = (Vector)groupCache.get(users.nextElement());
Enumeration e = group.elements();
while(e.hasMoreElements()){
String gname=(String)e.nextElement();
if (!groups.contains(gname)){
groups.add(gname);
}
}
}
return groups.elements();
}

/**
* Returns enumeration of groups that a particular user belongs to.
*
*@exception NoSuchUserException
*/
public Enumeration getGroupNames(String user)
throws NoSuchUserException
{
Vector groupInfo = (Vector)groupCache.get(user);
if (groupInfo.isEmpty()){
log("No Such user "+user);
throw new NoSuchUserException("User not available. Check the username - "+user);
}
return groupInfo.elements();
}


/**
* Refreshes the realm data so that new users/groups are visible.
*
*/
public void refresh() throws BadRealmException
{
loadUsers();

}

/**
* Checks the authentication of a user and returns the groups it belongs to.
*
* @return groups that this particular user belongs to
*/
public String[] authenticate(String user, String password)
{
String[] groups = null;
String pwd = (String)usrpwdCache.get(user);
log("=>user="+user+";pwd="+pwd);

if(!usrpwdCache.containsKey(user)){
log("No Such User,"+user);
return null;
}

pwd = (String)usrpwdCache.get(user);
if (password.equals(pwd)){
Vector v = (Vector)groupCache.get(user);
Enumeration g = v.elements();
int index=0;
groups = new String[v.capacity()];
while(g.hasMoreElements()){
groups[index++]=(String)g.nextElement();
}
} else{
log("Login Failed for "+user+". Wrong Password!");
return null;
}

return groups;
}

/*
* Helper methods.
*
* Simple message print method used throught the program
*/
public void log(String mesg){
_logger.log(Level.INFO, "SimpleCustomRealm:"+mesg );
}

}

 
Configuration Procedure

There are three key steps in configuring a realm, including your own customized realm:

  • Specify the login module
  • Specify realm information
  • Restart the server

To configure the realm, do the following:

  1. Specify the JAAS LoginModule in the domain's login configuration file appserver-domain-dir/config/login.conf. Fill in the following and append to the login.conf file.
  2.  jaas-context-name{
    jaas-login-module-class required;
    }

    For example,

    simpleCustomRealm {
    samples.security.customrealm.appserv.SimpleCustomLoginModule required; };

    1. Add the realm to the security service in the domain configuration file.

      Use Admin CLI/GUI to add the realm, or manually edit the file admin-domain-dir/config/domain.xml

      When using the asadmin CLI, use the --help option for help on usage:

    asadmin create-auth-realm  --help
    

    Using the asadmin CLI, for example:

    asadmin create-auth-realm   --user  admin
    --password admin_password
    --host localhost
    --port 4848
    --classname
    samples.security.customrealm.appserv.SimpleCustomRealm
    --property
    "jaas-context=simpleCustomRealm:auth-type=simplecustomrealm"
    mymemoryrealm

    If you want to add manually, edit the domain.xml file as shown in the following example:

     <auth-realm classname="samples.security.customrealm.appserv.SimpleCustomRealm"  
           name="mymemoryrealm">
              <property name="jaas-context" value="simpleCustomRealm"/>
              <property name="auth-type" value="simplecustomrealm"/>
       </auth-realm>
    

    1. Copy the LoginModule and Realm classes, and set the classpath suffix in the application server.

      1. Copy the login module, realm class, and all dependent classes into the application server domain classes directory appserver-domain-dir/lib/classes.

      2. Set the classpath suffix manually with the previous path in the appserver-domain-dir/config/domain.xml file as shown in the following example, or use the asadmin set command.
     

    <java-config classpath-suffix="<appserver-domain-dir>/lib/classes" debug-enabled="false" 
    debug-options="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044"
    env-classpath-ignored="true" java-home="${com.sun.aas.javaRoot}"
    javac-options="-g" rmic-options="-iiop -poa -alwaysgenerate -keepgenerated -g"
    server-classpath="${com.sun.aas.javaRoot}/lib/tools.jar${path.separator}$
    {com.sun.aas.installRoot}/lib/install/applications/jmsra/imqjmsra.jar$
    {path.separator}${com.sun.aas.imqLib}/jaxm-api.jar${path.separator}$
    {com.sun.aas.imqLib}/fscontext.jar${path.separator}$
    {com.sun.aas.antLib}/ant.jar">

    1. Restart the server. Make sure that the realm is properly loaded.

      Check admin-domain-dir/logs/server.log to see whether the aforementioned realm was properly loaded or not. The init() method of the realm should be invoked by the server. If it is not, double-check the previous steps to see if the realm has loaded properly (make sure that the realm has been recognized). Also, check to see if there are any classpath issues.


    Now you are ready to use the previous realm (mymemoryrealm) in your applications or modules for authentication.

    For example, to use the aforementioned realm in your Enterprise Java Bean, modify the sun-ejb-jar.xml and/or web.xml and/or sun-application.xml files as follows:

       <!-- sun-ejb-jar.xml -->
    <enterprise-beans>
    <ejb>
    <ejb-name>SecAuthTestBean</ejb-name>
    <jndi-name>SecAuthTestBeanJndiName</jndi-name>
    <ior-security-cofig>
    <as-context>
    <auth-method>USERNAME_PASSWORD</auth-method>
    <realm>mymemoryrealm</realm>
    <required>true</required>
    </as-context>
    </ior-security-config>
    </ejb>
    </enterprise-beans>


    <!-- web.xml -->
    <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>mymemoryrealm</realm-name>
    </login-config>


    <!-- sun-application.xml -->
    <sun-application>
    <realm>mymemoryrealm</realm>
    </sun-application>

 
References
  1. Securing J2EE Applications

  2. Java Authentication and Authorization Service (JAAS)

  3. Java Platform, Enterprise Edition 5 (Java EE 5)

 
About the Authors
Harpreet Singh is a member of the technical staff for Sun Java System Application Server and is the lead of the Security team in Application Server 8.0. He has been the Security lead in J2EE RI 1.3 and J2EE 1.4. He has been at Sun for the last three years and holds a master's degree from the University of Cincinnati.

Jagadesh Babu Munta is a member of the technical staff for Sun Java System Application Server. He is working on Security Quality and is also leading the Quality team. He has been at Sun for more than three years, working on application servers.

 
Acknowledgements
Thanks to Shing Wai Chan, Rick Palkovic and Cathy Arima for their suggestions in improving the article.