Custom login module development for a system login configuration

 

Custom login module development for a system login configuration

For WebSphere Application Server, multiple Java Authentication and Authorization Service (JAAS) plug-in points exist for configuring system logins. WebSphere Application Server uses system login configurations to authenticate incoming requests, outgoing requests, and internal server logins. Application login configurations are called by Java 2 Platform, Enterprise Edition (J2EE) applications for obtaining a Subject that is based on specific authentication information. This login configuration enables the application to associate the Subject with a specific protected remote action. The Subject is picked up on the outbound request processing. The following list identifies the main system plug-in points. If you write a login module that adds information to the Subject of a system login, these are the main login configurations to plug in:

WEB_INBOUND login configuration

The WEB_INBOUND login configuration authenticates Web requests. Figure 1 shows an example of a configuration using a trust association interceptor (TAI) that creates a Subject with the initial information that is passed into the WEB_INBOUND login configuration. If the trust association interceptor is not configured, the authentication process goes directly to the WEB_INBOUND system login configuration, which consists of all of the login modules combined in Figure 1. Figure 1 shows where you can plug in custom login modules and where the ltpaLoginModule and the wsMapDefaultInboundLoginModule login modules are required.

Figure 1

For more detailed information on the WEB_INBOUND configuration including its associated callbacks, see "RMI_INBOUND, WEB_INBOUND, DEFAULT" in System login configuration entry settings for Java Authentication and
Authorization Service.

RMI_OUTBOUND login configuration

The RMI_OUTBOUND login configuration is a plug point for handling outbound requests. WebSphere Application Server uses this plug point to create the serialized information that is sent downstream based on the invocation Subject passed in and other security context information such as propagation tokens. A custom login module can use this plug point to change the identity. For more information, see Configuring outbound mapping to a different target realm. Figure 2 shows where you can plug in custom login modules and shows where the wsMapCSIv2OutboundLoginModule login module is required.

Figure 2

For more information on the RMI_OUTBOUND login configuration including its associated callbacks, see "RMI_OUTBOUND" in System login configuration entry settings for Java Authentication and
Authorization Service.

RMI_INBOUND login configuration

The RMI_INBOUND login configuration is a plug point that handles inbound authentication for enterprise bean requests. WebSphere Application Server uses this plug point for either an initial login or a propagation login. For more information about these two login types, see Security attribute propagation. During a propagation login, this plug point is used to deserialize the information that is received from an upstream server. A custom login module can use this plug point to change the identity, handle custom tokens, add custom objects into the Subject, and so on. For more information on changing the identity using a Hashtable object, which is referenced in figure 3, see Configuring inbound identity mapping. Figure 3 shows where you can plug in custom login modules and shows that the ltpaLoginModule and the wsMapDefaultInboundLoginModule login modules are required.

Figure 3

For more information on the RMI_INBOUND login configuration, including its associated callbacks, see "RMI_INBOUND, WEB_INBOUND, DEFAULT" in System login configuration entry settings for Java Authentication and Authorization Service.

DEFAULT login configuration

The DEFAULT login configuration is a plug point that handles all of the other types of authentication requests, including administrative Simple Object Access Protocol (SOAP) requests and internal authentication of the server ID. Propagation logins typically do not occur at this plug point.

For more information on the DEFAULT login configuration including its associated callbacks, see "RMI_INBOUND, WEB_INBOUND, DEFAULT" in System login configuration entry settings for Java Authentication and Authorization Service.

Writing a login module When you write a login module that plugs into a WebSphere Application Server application login or system login configuration, read the JAAS programming model, which is located at: http://java.sun.com/products/jaas. The JAAS programming model provides basic information about JAAS. However, before writing a login module for the WebSphere Application Server environment, read the following sections in this article:

Useable callbacks

Each login configuration must document the callbacks that are recognized by the login configuration. However, the callbacks are not always passed data. The login configuration must contain logic to know when specific information is present and how to use the information. For example, if you write a custom login module that can plug into all four of the pre-configured system login configurations mentioned previously, three sets of callbacks might be presented to authenticate a request. Other callbacks might be present for other reasons, including propagation and making other information available to the login configuration. Login information can be presented in the following combinations:

User name (NameCallback) and password (PasswordCallback)

This information is a typical authentication combination.

User name only (NameCallback)

This information is used for identity assertion, trust association interceptor (TAI) logins, and certificate logins.

Token (WSCredTokenCallbackImpl)

This information is for Lightweight Third Party Authentication (LTPA) token validation.

Propagation token list (WSTokenHolderCallback)

This information is used for a propagation login.
The first three combinations are used for typical authentication. However, when the WSTokenHolderCallback callback is present in addition to one of the first three information combinations, the login is called a propagation login. A propagation login means that some security attributes are propagated to this server from another server. The servers can reuse these security attributes if the authentication information validates successfully. In some cases, a WSTokenHolderCallback callback might not have sufficient attributes for a full login. Check the requiresLogin method on the WSTokenHolderCallback callback to determine if a new login is required. You can always ignore the information returned by the requiresLogin method, but, as a result, you might duplicate information. The following list contains the callbacks that might be present in the system login configurations. The list includes the callback name and a description of their responsibility.

callbacks[0] = new javax.security.auth.callback.NameCallback("Username: ");

This callback handler collects the user name for the login. The result can be the user name for a basic authentication login (user name and password) or a user name for an identity assertion login.

callbacks[1] = new javax.security.auth.callback.PasswordCallback("Password: ", false);

This callback handler collects the password for the login.

callbacks[2] = new com.ibm.websphere.security.auth.callback.WSCredTokenCallbackImpl("Credential Token: ");

This callback handler collects the Lightweight Third Party Authentication (LTPA) token or other token type for the login. This callback handler is typically present when a user name and password is not present.

callbacks[3] = new com.ibm.wsspi.security.auth.callback.WSTokenHolderCallback("Authz Token List: ");

This callback handler collects the ArrayList of TokenHolder objects that are returned from a call to the WSOpaqueTokenHelper.createTokenHolderListFromOpaqueToken () API using the Common Secure Interoperability Version 2 (CSIv2) authorization token as input.

callbacks[4] = new com.ibm.websphere.security.auth.callback.WSServletRequestCallback("HttpServletRequest: ");

This callback handler collects the HTTP servlet request object, if present. This callback handler enables login modules to get information from the HTTP request for use in the login. This callback handler is presented from the WEB_INBOUND login configuration only.

callbacks[5] = new com.ibm.websphere.security.auth.callback.WSServletResponseCallback("HttpServletResponse: ");

This callback handler collects the HTTP servlet response object, if present. This callback handler enables login modules to put information into the HTTP response as a result of the login. An example of this situation might be adding the SingleSignonCookie cookie to the response.This callback handler is presented from the WEB_INBOUND login configuration only.

callbacks[6] = new com.ibm.websphere.security.auth.callback.WSAppContextCallback("ApplicationContextCallback: ");

This callback handler collects the Web application context that is used during the login. This callback handler consists of a HashMap object, which contains the application name and the redirect web address, if present. The callback handler is presented from the WEB_INBOUND login configuration only.

Shared state variables

Shared state variables are used to share information between login modules during the login phase. The following list contains recommendations for using the shared state variables:

The com.ibm.wsspi.security.token.AttributeNameConstants.WSCREDENTIAL_PROPERTIES_KEY shared state variable can inform the WebSphere Application Server login configurations about asserted privilege attributes. This variable references the com.ibm.wsspi.security.cred.propertiesObject property. Associate a java.util.Hashtable with this property. This hashtable contains properties that are used by WebSphere Application Server for login purposes and ignores the callback information. This hashtable enables a custom login module, which is carried out first in the login configuration, to map user identities or enable WebSphere Application Server to avoid making unnecessary user registry calls if you already have the required information. For more information, see Configuring inbound identity mapping. If you want to access the objects that WebSphere Application Server creates during a login, refer to the following shared state variables. The variables are set in the following login modules: ltpaLoginModule, swamLoginModule, and wsMapDefaultInboundLoginModule.

Shared state variable

com.ibm.wsspi.security.auth.callback.Constants.WSPRINCIPAL_KEY

Purpose

The com.ibm.websphere.security.auth.WSPrincipal object. See the WebSphere Application Server API documentation for application programming interface (API) usage. This shared state variable is for read-only purposes. Do not set this variable in the shared state for custom login modules.

The login module in which variables are set

ltpaLoginModule, swamLoginModule, and wsMapDefaultInboundLoginModule

Shared state variable

com.ibm.wsspi.security.auth.callback.Constants.WSCREDENTIAL_KEY

Purpose

The com.ibm.websphere.security.cred.WSCredential object. See the WebSphere Application Server API documentation for API usage. This shared state variable is for read-only purposes. Do not set this variable in the shared state for custom login modules.

The login module in which variables are set

wsMapDefaultInboundLoginModule

Shared state variable

com.ibm.wsspi.security.auth.callback.Constants.WSAUTHZTOKEN_KEY

Purpose

The default com.ibm.wsspi.security.token.AuthorizationToken object. Login modules can use this object to set custom attributes plugged in after the wsMapDefaultInboundLoginModule login module. The information set here is propagated downstream and is available to the application. See the WebSphere Application Server API documentationfor API usage.

Initial versus propagation logins

As mentioned previously, some logins are considered initial logins because of the following reasons:

Other logins are considered propagation logins when a WSTokenHolderCallback callback is present and contains sufficient information from a sending server to recreate all the required objects needed by WebSphere Application Server run time. In cases where there is sufficient information for the WebSphere Application Server run time, the information you might add to the Subject is likely to exist from the previous login. To verify if your object is present, you can get access to the ArrayList object that is present in the WSTokenHolderCallback callback, and search through this list looking at each TokenHolder getName method. This search is used to determine if WebSphere Application Server is deserializing your custom object during this login. Check the class name returned from the getName method using the String startsWith method because the run time might add additional information at the end of the name to know which Subject is set to add the custom object after deserialization.

Example

The following code snippet can be used in your login() method to determine when sufficient information is present. For another example, see Configuring inbound identity mapping.

// This is a hint provided by WebSphere Application Server that 
// sufficient propagation information does not exist and, therefore, 
// a login is required to provide the sufficient information. In this 
// situation, a Hashtable login might be used.
boolean requiresLogin = ((com.ibm.wsspi.security.auth.callback.
WSTokenHolderCallback) callbacks[1]).requiresLogin();

if (requiresLogin)
{
// Check to see if your object exists in the TokenHolder list, 
if not, add it.
java.util.ArrayList authzTokenList = ((WSTokenHolderCallback) callbacks[6]).
getTokenHolderList();boolean found = false;

if (authzTokenList != null)
{
Iterator tokenListIterator = authzTokenList.iterator();

while (tokenListIterator.hasNext())
{
com.ibm.wsspi.security.token.TokenHolder th = (com.ibm.wsspi.security.token.
TokenHolder) tokenListIterator.next();

if (th != null && th.getName().startsWith("com.acme.myCustomClass"))
{
found=true;
break;
}
}
if (!found)
{
// go ahead and add your custom object.
}
} 
}
else {
// This code indicates that sufficient propagation information is present. 
// User registry calls are not needed by WebSphere Application Server to 
// create a valid Subject. This code might be a no-op in your login module.
}

Sample custom login module

You can use the following sample to get ideas on how to use some of the callbacks and shared state variables.

{
 // Defines your login module variables  com.ibm.wsspi.security.token.AuthenticationToken customAuthzToken = null;
 com.ibm.wsspi.security.token.AuthenticationToken defaultAuthzToken = null;
 com.ibm.websphere.security.cred.WSCredential credential = null;
 com.ibm.websphere.security.auth.WSPrincipal principal = null;
 private javax.security.auth.Subject _subject;
 private javax.security.auth.callback.CallbackHandler _callbackHandler;
 private java.util.Map _sharedState;
 private java.util.Map _options;

 public void initialize(Subject subject, CallbackHandler callbackHandler, 
     Map sharedState, Map options) 
 {
  _subject = subject;
  _callbackHandler = callbackHandler;
  _sharedState = sharedState;
  _options = options;
 }

 public boolean login() throws LoginException 
 {
  boolean succeeded = true;

  // Gets the CALLBACK information   javax.security.auth.callback.Callback callbacks[] = new javax.security.
        auth.callback.Callback[7];
  callbacks[0] = new javax.security.auth.callback.NameCallback(
        "Username: ");
  callbacks[1] = new javax.security.auth.callback.PasswordCallback(
        "Password: ", false);
  callbacks[2] = new com.ibm.websphere.security.auth.callback.
        WSCredTokenCallbackImpl ("Credential Token: ");
  callbacks[3] = new com.ibm.wsspi.security.auth.callback.
        WSServletRequestCallback ("HttpServletRequest: ");
  callbacks[4] = new com.ibm.wsspi.security.auth.callback.
        WSServletResponseCallback ("HttpServletResponse: ");
  callbacks[5] = new com.ibm.wsspi.security.auth.callback.
        WSAppContextCallback ("ApplicationContextCallback: ");
  callbacks[6] = new com.ibm.wsspi.security.auth.callback.
         WSTokenHolderCallback ("Authz Token List: ");
            
  try   {
   callbackHandler.handle(callbacks);
  } 
  catch (Exception e)
  {
   // Handles exceptions    throw new WSLoginFailedException (e.getMessage(), e);
  }

  // Sees which callbacks contain information   uid = ((NameCallback) callbacks[0]).getName();
  char password[] = ((PasswordCallback) callbacks[1]).getPassword();
  byte[] credToken = ((WSCredTokenCallbackImpl) callbacks[2]).getCredToken();
  javax.servlet.http.HttpServletRequest request = ((WSServletRequestCallback) 
        callbacks[3]).getHttpServletRequest();
  javax.servlet.http.HttpServletResponse response = ((WSServletResponseCallback) 
        callbacks[4]).getHttpServletResponse();
  java.util.Map appContext = ((WSAppContextCallback) 
        callbacks[5]).getContext();
  java.util.List authzTokenList = ((WSTokenHolderCallback) 
        callbacks[6]).getTokenHolderList();

  // Gets the SHARED STATE information   principal = (WSPrincipal) _sharedState.get(com.ibm.wsspi.security.
        auth.callback.Constants.WSPRINCIPAL_KEY);
  credential = (WSCredential) _sharedState.get(com.ibm.wsspi.security.
        auth.callback.Constants.WSCREDENTIAL_KEY);
  defaultAuthzToken = (AuthorizationToken) _sharedState.get(com.ibm.
        wsspi.security.auth.callback.Constants.WSAUTHZTOKEN_KEY);

     // What you tend to do with this information depends upon the scenario      // that you are trying to accomplish. This example demonstrates how to 
     // access various different information:
     // - Determine if a login is initial versus propagation      // - Deserialize a custom authorization token (For more information, see 
     //   Security attribute propagation
     // - Add a new custom authorization token (For more information, see 
     //   Security attribute propagation
     // - Look for a WSCredential and read attributes, if found.
     // - Look for a WSPrincipal and read attributes, if found.
     // - Look for a default AuthorizationToken and add attributes, if found.
     // - Read the header attributes from the HttpServletRequest, if found.
     // - Add an attribute to the HttpServletResponse, if found.
     // - Get the web application name from the appContext, if found.

     // - Determines if a login is initial versus propagation. This is most 
     //  useful when login module is first.
  boolean requiresLogin = ((WSTokenHolderCallback) callbacks[6]).requiresLogin();

  // initial login - asserts privilege attributes based on user identity   if (requiresLogin)
  {

   // If you are validating a token from another server, there is an 
       // application programming interface  (API) to get the uniqueID from it.
   if (credToken != null && uid == null)
   {
    try     {
     String uniqueID = WSSecurityPropagationHelper.
               validateLTPAToken(credToken);
     String realm = WSSecurityPropagationHelper.getRealmFromUniqueID
                (uniqueID);
            // Now set it to the UID so you can use that to either map or 
            // login with.
     uid = WSSecurityPropagationHelper.getUserFromUniqueID (uniqueID);
    }
    catch (Exception e)
    {
     // handle exception     }
   }
       // Adds a Hashtable to shared state.
       // Note: You can perform custom mapping on the NameCallback value returned      
       // to change the identity based upon your own mapping rules.
   uid = mapUser (uid);   

   // Gets the default InitialContext for this server.
   javax.naming.InitialContext ctx = new javax.naming.InitialContext();

   // Gets the local UserRegistry object.
   com.ibm.websphere.security.UserRegistry reg = (com.ibm.websphere.security.
            UserRegistry) ctx.lookup("UserRegistry");    

       // Gets the user registry uniqueID based on the uid specified in the 
       // NameCallback.
   String uniqueid = reg.getUniqueUserId(uid);
    uid = WSSecurityPropagationHelper.getUserFromUniqueID (uniqueID);
   
   // Gets the display name from the user registry based on the uniqueID.
   String securityName = reg.getUserSecurityName(uid);
 
   // Gets the groups associated with this uniqueID.
   java.util.List groupList = reg.getUniqueGroupIds(uid);
   
       // Creates the java.util.Hashtable with the information you gathered from        // the UserRegistry.
   java.util.Hashtable hashtable = new java.util.Hashtable();
   hashtable.put(com.ibm.wsspi.security.token.AttributeNameConstants.
           WSCREDENTIAL_UNIQUEID, uniqueid);
   hashtable.put(com.ibm.wsspi.security.token.AttributeNameConstants.
           WSCREDENTIAL_SECURITYNAME, securityName);
   hashtable.put(com.ibm.wsspi.security.token.AttributeNameConstants.
           WSCREDENTIAL_GROUPS, groupList);

       // Adds a cache key that is used as part of the lookup mechanism for        // the created Subject. The cache key can be an Object, but should 
       // implement the toString() method. Make sure the cacheKey contains        // enough information to scope it to the user and any additional        // attributes that you use. If you do not specify this property the 
       // Subject is scoped to the WSCREDENTIAL_UNIQUEID returned, by default.
   hashtable.put(com.ibm.wsspi.security.token.AttributeNameConstants.
          WSCREDENTIAL_CACHE_KEY,
     "myCustomAttribute" + uniqueid);

    // Adds the hashtable to the sharedState of the Subject.
    _sharedState.put(com.ibm.wsspi.security.token.AttributeNameConstants.
             WSCREDENTIAL_PROPERTIES_KEY,hashtable);
  }
  // propagation login - process propagated tokens   else   {
   // - Deserializes a custom authorization token. For more information, see 
       //    Security attribute propagation.
       //    This can be done at any login module plug in point (first, 
       //     middle, or last).
   if (authzTokenList != null)
   {
    // Iterates through the list looking for your custom token     for (int i=0; i<authzTokenList.size(); i++)
    {
     TokenHolder tokenHolder = (TokenHolder)authzTokenList.get(i);
 
     // Looks for the name and version of your custom AuthorizationToken 
            // implementation      if (tokenHolder.getName().equals("com.ibm.websphere.security.token.
                CustomAuthorizationTokenImpl") && tokenHolder.getVersion() == 1)
     {
      // Passes the bytes into your custom AuthorizationToken constructor 
               // to deserialize       customAuthzToken = new          
       com.ibm.websphere.security.token.
                   CustomAuthorizationTokenImpl(tokenHolder.getBytes());
 
     }
    }
   }
        // - Adds a new custom authorization token (For more information,
        //   see Security attribute propagation)
        //    This can be done at any login module plug in point (first, middle,
        //    or last).
   else    { 
    // Gets the PRINCIPAL from the default AuthenticationToken. This must 
          // match all of the tokens.
    defaultAuthToken = (com.ibm.wsspi.security.token.AuthenticationToken) 
     sharedState.get(com.ibm.wsspi.security.auth.callback.Constants.
               WSAUTHTOKEN_KEY);
    String principal = defaultAuthToken.getPrincipal();
 
    // Adds a new custom authorization token. This is an initial login. 
          // Pass the principal into the constructor 
    customAuthzToken = new com.ibm.websphere.security.token.
               CustomAuthorizationTokenImpl(principal);
 
    // Adds any initial attributes     if (customAuthzToken != null)
    {
     customAuthzToken.addAttribute("key1", "value1");
     customAuthzToken.addAttribute("key1", "value2");
     customAuthzToken.addAttribute("key2", "value1");
     customAuthzToken.addAttribute("key3", "something different");
    } 
   }
  }
  
  // - Looks for a WSCredential and read attributes, if found.  
  //   This is most useful when plugged in as the last login module.
  if (credential != null)
  {
   try    {
    // Reads some data from the credential     String securityName = credential.getSecurityName();
    java.util.ArrayList = credential.getGroupIds();
   }
   catch (Exception e)
   {
    // Handles exceptions     throw new WSLoginFailedException (e.getMessage(), e);
   }
  }

  // - Looks for a WSPrincipal and read attributes, if found.
  //   This is most useful when plugged as the last login module.
  if (principal != null)
  {
   try    {
    // Reads some data from the principal     String principalName = principal.getName();
   }
   catch (Exception e)
   {
    // Handles exceptions     throw new WSLoginFailedException (e.getMessage(), e);
   }
  }

  // - Looks for a default AuthorizationToken and add attributes, if found.
  //   This is most useful when plugged in as the last login module.
  if (defaultAuthzToken != null)
  {
   try    {
    // Reads some data from the defaultAuthzToken     String[] myCustomValue = defaultAuthzToken.getAttributes ("myKey");
    // Adds some data if not present in the defaultAuthzToken     if (myCustomValue == null)
     defaultAuthzToken.addAttribute ("myKey", "myCustomData");
   }
   catch (Exception e)
   {
    // Handles exceptions     throw new WSLoginFailedException (e.getMessage(), e);
   }
  }

  // - Reads the header attributes from the HttpServletRequest, if found.
  //  This can be done at any login module plug in point (first, middle, 
     //  or last).
  if (request != null)
  {
   java.util.Enumeration headerEnum = request.getHeaders();
   while (headerEnum.hasMoreElements())
   {
    System.out.println ("Header element: " + (String)headerEnum.nextElement());
   }
  }

  // - Adds an attribute to the HttpServletResponse, if found      //  This can be done at any login module plug in point (first, middle,
     //  or last).
  if (response != null)
  {
   response.addHeader ("myKey", "myValue");
  }

  // - Gets the web application name from the appContext, if found   //   This can be done at any login module plug in point (first, middle,
     //   or last).
  if (appContext != null)
  {
   String appName = (String) appContext.get(com.ibm.wsspi.security.auth.
          callback.Constants.WEB_APP_NAME);
  }

  return succeeded;
 }

 public boolean commit() throws LoginException 
 {
  boolean succeeded = true;
  
  // Add any objects here that you have created and belong in the  
  // Subject. Make sure the objects are not already added. If you added  
  // any sharedState variables, remove them before you exit. If the abort() 
     // method gets called, make sure you cleanup anything added to the 
  // Subject here.  

  if (customAuthzToken != null)
  {
   // Sets the customAuthzToken token into the Subject    try    {
    // Do this in a doPrivileged code block so that application code           
          // does not need to add additional permissions     java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() 
    {
     public Object run() 
     {
      try       {
       // Adds the custom authorization token if it is not 
                 //  null and not already in the Subject                                 if ((customAuthzTokenPriv != null) &&    
         (!_subject.getPrivateCredentials().contains(customAuthzTokenPriv)))
       {
        _subject.getPrivateCredentials().add(customAuthzTokenPriv);
       }
      } 
      catch (Exception e)
      {
       throw new WSLoginFailedException (e.getMessage(), e);
      }

      return null;
     }
    });
   }
   catch (Exception e)
   {
    throw new WSLoginFailedException (e.getMessage(), e);
   }
  }

  return succeeded;
 }

 public boolean abort() throws LoginException 
 {
  boolean succeeded = true;

  // Makes sure to remove all objects that have already been added (both into the 
     // Subject and shared state).

  if (customAuthzToken != null)
  {
   // remove the customAuthzToken token from the Subject    try    {
    final AuthorizationToken customAuthzTokenPriv = customAuthzToken;
    // Do this in a doPrivileged block so that application code does not need 
          // to add additional permissions     java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() 
    {
     public Object run() 
     {
      try       {
       // Removes the custom authorization token if it is not 
                 // null and not already in the Subject                      if ((customAuthzTokenPriv != null) && 
                      (_subject.getPrivateCredentials().
                       contains(customAuthzTokenPriv)))
       {
        _subject.getPrivateCredentials().
                    remove(customAuthzTokenPriv);
       }
      } 
      catch (Exception e)
      {
       throw new WSLoginFailedException (e.getMessage(), e);
      }

      return null;
     }
    });
   }
   catch (Exception e)
   {
    throw new WSLoginFailedException (e.getMessage(), e);
   }
  }
  
  return succeeded;
 }


 public boolean logout() throws LoginException 
 {
  boolean succeeded = true;

  // Makes sure to remove all objects that have already been added 
     // (both into the Subject and shared state).

  if (customAuthzToken != null)
  {
   // Removes the customAuthzToken token from the Subject    try    {
    final AuthorizationToken customAuthzTokenPriv = customAuthzToken;
    // Do this in a doPrivileged code block so that application code does 
          // not need to add additional permissions     java.security.AccessController.doPrivileged(new java.security.
            PrivilegedAction() 
    {
     public Object run() 
     {
      try       {
       // Removes the custom authorization token if it is not null and not 
                 //  already in the Subject                      if ((customAuthzTokenPriv != null) && (_subject.
                     getPrivateCredentials().
                     contains(customAuthzTokenPriv)))
       {
        _subject.getPrivateCredentials().remove(customAuthzTokenPriv);
       }
      } 
      catch (Exception e)
      {
       throw new WSLoginFailedException (e.getMessage(), e);
      }

      return null;
     }
    });
   }
   catch (Exception e)
   {
    throw new WSLoginFailedException (e.getMessage(), e);
   }
  }
  
  return succeeded;
 
 }

}

After developing your custom login module for a system login configuration, you can configure the system login using either the administrative console or using the wsadmin utility. To configure the system login using the administrative console, click Security > Global security . Under Authentication, click JAAS Configuration > System logins . For more information on using the wsadmin utility for system login configuration, see Example: Customizing a server-side Java Authentication and Authorization Service authentication and login configuration. Also refer to the Example: Customizing a server-side Java Authentication and Authorization Service authentication and login configuration article for information on system login modules and to determine whether to add additional login modules.


Related concepts
Security attribute propagation

Related tasks
Configuring inbound identity mapping
Configuring outbound mapping to a different target realm

Related reference

System login configuration entry settings for Java Authentication and
Authorization Service
Customizing a server-side Java Authentication and Authorization Service authentication and login configuration
Customizing a server-side Java Authentication and Authorization Service authentication and login configuration


Searchable topic ID: rsec_jaascustlogmod