Using the default authorization token to propagate security attributes

This topic explains how WebSphere® Application Server uses the default authorization token. Consider using the default authorization token when you are looking for a place to add string attributes that get propagated downstream.

About this task

However, make sure that the attributes you add to the authorization token are specific to the user that is associated with the authenticated Subject. If they are not specific to a user, the attributes probably belong in the propagation token, which is also propagated with the request. For more information on the propagation token, see Using the default propagation token to propagate security attributes. To add attributes into the authorization token, you must plug in a custom login module into the various system login modules that are configured. Any login module configuration that has the com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule implementation configured can receive propagated information and can generate propagation information that can be sent outbound to another server.

If propagated attributes are not presented to the login configuration during an initial login, a default authorization token is created in the wsMapDefaultInboundLoginModule login module after the login occurs in the ltpaLoginModule login module. You can obtain a reference to the default authorization token from the login method using the sharedState hashmap. You must plug in the custom login module after the wsMapDefaultInboundLoginModule implementation for WebSphere Application Server to see the default authorization token.

For more information on the Java™ Authentication and Authorization Service (JAAS) programming model, see the Security: Resources for learning article.

Procedure

  • Obtain a reference to the default authorization token from the login method.
  • Add attributes to the token.
  • Read existing attributes used for authorization.
  • [IBM i]Add your custom login module to the profile_root/classes directory.
  • [AIX Solaris HP-UX Linux Windows][z/OS]Ensure that your custom login module code is trusted.
    Whenever you plug a custom login module into the WebSphere Application Server login infrastructure, you must ensure that the code is trusted. When you add the login module into the app_server_root/classes directory, it has Java 2 Security AllPermissions permissions. It is recommended that you add your login module and other infrastructure classes into a private directory. However, if you use a private directory, modify the $(WAS_INSTALL_ROOT)/properties/server.policy file so that the private directory, Java archive (JAR) file, or both have the permissions that are needed to run the application programming interfaces (API) that are called from the login module. Because the login module might run after the application code on the call stack, you might consider adding a doPrivileged code block so that you do not need to add additional permissions to your applications.
  • Modify the authorization token factory to use a token factory other than the default token factory.

    When WebSphere Application Server generates a default authorization token, the application server utilizes the TokenFactory class that is specified using the com.ibm.wsspi.security.token.authorizationTokenFactory property.

    The com.ibm.ws.security.ltpa.AuthzPropTokenFactory token factory is the default. This token factory encodes the data, but does not encrypt the data in the authorization token. Because the authorization token typically flows over Common Secure Interoperability Version 2 (CSIv2) using Secure Sockets Layer (SSL), encrypting the token is not necessary. However, if you need additional security for the authorization token, you can associate a different token factory implementation with this property to get encryption. For example, if you associate the com.ibm.ws.security.ltpa.LTPAToken2Factory token factory with this property, the token uses Advanced Encryption Standard (AES) encryption. However, you need to weigh the performance impacts against your security needs. Adding sensitive information to the authorization token is one reason to change the token factory implementation to something that encrypts rather than just encodes.

    1. Open the administrative console.
    2. Click Security > Global security.
    3. Under Additional properties, click Custom properties.
  • Perform your own signing and encryption of the default authorization token.
    If you want to perform your own signing and encryption of the default authorization token, you must implement the following classes:
    • com.ibm.wsspi.security.ltpa.Token
    • com.ibm.wsspi.security.ltpa.TokenFactory
    Your token factory implementation instantiates and validates your token implementation. You can use the Lightweight Third Party Authentication (LTPA) keys that are passed into the initialize method of the token factory or you can use your own keys. If you use your own keys, they must be the same everywhere to validate the tokens that are generated using those keys. See the API documentation, that is available through a link on the front page of the documentation, for more information on implementing your own custom token factory.
  • Associate your token factory with the default authorization token.
    To associate your token factory with the default authorization token, using the administrative console, complete the following steps:
    1. Click Security > Global security.
    2. Under Additional properties, click Custom properties.
    3. Locate the com.ibm.wsspi.security.token.authorizationTokenFactory property and verify that the value of this property matches your custom token factory implementation.
    4. Verify that your implementation classes are put into the app_server_root/classes directory so that the WebSphere Application Server class loader can load the classes.
    5. [AIX Solaris HP-UX Linux Windows][z/OS]Verify that your implementation classes are put into the ${USER_INSTALL_ROOT}/classes directory so that the WebSphere Application Server class loader can load the classes.
    6. [IBM i]Verify that the QEJBSVR user profile has read, write, and execute (*RWX) authority to the classes directory. You can use the Work with Authority (WRKAUT) command to view the authority permissions for the directory.

Example

The following example shows the complete task of obtaining a reference to the default authorization token from the login method, adding attributes to the token, and reading from the existing attributes that are used for authorization.
public customLoginModule() 
{
	public void initialize(Subject subject, CallbackHandler callbackHandler, 
          Map sharedState, Map options) 
	{
     // (For more information on initialization, see
     // Developing custom login modules for a system login configuration for JAAS.)

		// Get a reference to the sharedState map that is passed in during initialization.
		_sharedState = sharedState;
	}

	public boolean login() throws LoginException 
	{
     // (For more information on what to do during login, see
     // Developing custom login modules for a system login configuration for JAAS.)

		// Look for the default AuthorizationToken in the shared state
		defaultAuthzToken  = (com.ibm.wsspi.security.token.AuthorizationToken) 
       sharedState.get 
					(com.ibm.wsspi.security.auth.callback.Constants.WSAUTHZTOKEN_KEY);

		// Might not always have one of these generated. It depends on the login 
     // configuration setup.
		if (defaultAuthzToken != null)
		{
			try
			{
				// Add a custom attribute
				defaultAuthzToken.addAttribute("key1", "value1");

				// Determine all of the attributes and values that exist in the token.
				java.util.Enumeration listOfAttributes = defaultAuthorizationToken.
              getAttributeNames();
				
				while (listOfAttributes.hasMoreElements())
				{
					String key = (String) listOfAttributes.nextElement();

					String[] values = (String[]) defaultAuthorizationToken.getAttributes (key);

					for (int i=0;  i<values.length; i++)
					{
						System.out.println ("Key: " + key + ", Value[" + i + "]: " 
                  + values[i]);
					}
				}

				// Read the existing uniqueID attribute.
				String[] 	uniqueID = defaultAuthzToken.getAttributes 
						(com.ibm.wsspi.security.token.AttributeNameConstants.
               WSCREDENTIAL_UNIQUEID);

					// Getthe uniqueID from the String[]
					String unique_id = (uniqueID != null && 
                uniqueID[0] != null) ? uniqueID[0] : "";

				// Read the existing expiration attribute.
				String[] 	expiration = defaultAuthzToken.getAttributes 
						(com.ibm.wsspi.security.token.AttributeNameConstants.
               WSCREDENTIAL_EXPIRATION);

					// An example of getting a long expiration value from the string array.
					long expire_time = 0;
					if (expiration != null && expiration[0] != null) 
						expire_time = Long.parseLong(expiration[0]);

				// Read the existing display name attribute.
				String[] 	securityName = defaultAuthzToken.getAttributes 
						(com.ibm.wsspi.security.token.AttributeNameConstants.
               WSCREDENTIAL_SECURITYNAME);

					// Get the display name from the String[]
					String display_name = (securityName != null && 
                securityName[0] != null) ? securityName[0] : "";


				// Read the existing long securityName attribute.
				String[] 	longSecurityName = defaultAuthzToken.getAttributes 
					(com.ibm.wsspi.security.token.AttributeNameConstants.
             WSCREDENTIAL_LONGSECURITYNAME);

				// Get the long security name from the String[]
				String long_security_name = (longSecurityName != null && 
              longSecurityName[0] != null) ? longSecurityName[0] : "";


				// Read the existing group attribute.
				String[] 	groupList = defaultAuthzToken.getAttributes 
						(com.ibm.wsspi.security.token.AttributeNameConstants.
               WSCREDENTIAL_GROUPS);

				// Get the groups from the String[]
				ArrayList groups = new ArrayList();
				if (groupList != null)
				{
					for (int i=0; i<groupList.length; i++)
					{
						System.out.println ("group[" + i + "] = " + groupList[i]);
						groups.add(groupList[i]);
					}
				}
			}
			catch (Exception e)
			{
				throw new WSLoginFailedException (e.getMessage(), e);
			}
		}

	}

	public boolean commit() throws LoginException 
	{
		// (For more information on what to do during commit, see 
     // Developing custom login modules for a system login configuration for JAAS.)

	}

	private java.util.Map _sharedState = null;
	private com.ibm.wsspi.security.token.AuthorizationToken defaultAuthzToken = null;
}
.