A default propagation token is located on the running thread
for applications and the security infrastructure to use. WebSphere
Application Server propagates this default propagation token downstream
and the token stays on the thread where the invocation lands at each
hop.
About this task
The data is available from within the container
of any resource where the propagation token lands. Remember that you
must enable the propagation feature at each server where a request
is sent for propagation to work. Make sure that you enable security
attribute propagation for all of the cells in your environment where
you want propagation
There is a WSSecurityHelper class that
has application programming interfaces (APIs) for accessing the PropagationToken
attributes. This topic documents the usage scenarios and includes
examples. A close relationship exists between the propagation token
and the work area feature. The main difference between these features
is that after you add attributes to the propagation token, you cannot
change the attributes. You cannot change these attributes so that
the security runtime can add auditable information and have that information
remain there for the life of the invocation. Any time that you add
an attribute to a specific key, an ArrayList object is stored to hold
that attribute. Any new attribute that is added with the same key
is added to the ArrayList object. When you call getAttributes, the
ArrayList object is converted to a String array and the order is preserved.
The first element in the String array is the first attribute added
for that specific key.
In the default propagation token, a change
flag is kept that logs any data changes to the token. These changes
are tracked to enable WebSphere Application Server to know when to
send the authentication information downstream again so that the downstream
server has those changes. Normally, Common Secure Interoperability
Version 2 (CSIv2) maintains a session between servers for an authenticated
client. If the propagation token changes, a new session is generated
and subsequently a new authentication occurs. Frequent changes to
the propagation token during a method cause frequent downstream calls.
If you change the token prior to making many downstream calls or you
change the token between each downstream call, you might impact security
performance.
- Obtain the server list from the default propagation
token.
Every time the propagation token is propagated
and used to create the authenticated Subject, either horizontally
or downstream, the name of the receiving application server is logged
into the propagation token.
The format of the host is "Cell:Node:Server",
which provides you access to the cell name, node name, and server
name of each application server that receives the invocation.
The
format of each server in the list is: cell:node_name:server_name.
The output, for example, is: myManager:node1:server1
The following code provides you with this list of names
and can be called from a Java 2 Platform, Enterprise Edition (J2EE)
application:
String[] server_list = null;
// If security is disabled on this application server, do not bother checking
if (com.ibm.websphere.security.WSSecurityHelper.isServerSecurityEnabled())
{
try
{
// Gets the server_list string array
server_list = com.ibm.websphere.security.WSSecurityHelper.getServerList();
}
catch (Exception e)
{
// Performs normal exception handling for your application
}
if (server_list != null)
{
// print out each server in the list, server_list[0] is the first server
for (int i=0; i<server_list.length; i++)
{
System.out.println("Server[" + i + "] = " + server_list[i]);
}
}
}
- Obtain the list of callers, using the getCallerList
API.
A default propagation token is generated any time
an authenticated user is set on the running thread or anyone tries
to add attributes to the propagation token. Whenever an authenticated
user is set on the thread, the user is logged in the default propagation
token. At times, the same user might be logged in multiple times if
the RunAs user is different from the caller. The following list provides
the rules that are used to determine if a user that is added to the
thread gets logged into the propagation token:
- The current Subject must be authenticated. For example, an unauthenticated
Subject is not logged.
- The current authenticated Subject is logged if a Subject is not
previously logged.
- The current authenticated Subject is logged if the last authenticated
Subject that is logged does not contain the same user.
- The current authenticated Subject is logged on each unique application
server that is involved in the propagation process.
The format of each caller in the list is: cell:node_name:server_name:realm:port_number/securityName.
The output, for example, is: myManager:node1:server1:ldap.austin.ibm.com:389/jsmith.
The following code sample shows how to use the getCallerList
API:
String[] caller_list = null;
// If security is disabled on this application server, do not check the caller list
if (com.ibm.websphere.security.WSSecurityHelper.isServerSecurityEnabled())
{
try
{
// Gets the caller_list string array
caller_list = com.ibm.websphere.security.WSSecurityHelper.getCallerList();
}
catch (Exception e)
{
// Performs normal exception handling for your application
}
if (caller_list != null)
{
// Prints out each caller in the list, caller_list[0] is the first caller
for (int i=0; i<caller_list.length;i++)
{
System.out.println("Caller[" + i + "] = " + caller_list[i]);
}
}
}
- Obtain the security name of the first authenticated
user, using the getFirst Caller API.
Whenever you want
to know which authenticated caller started the request, you can call
the getFirstCaller method and the caller list is parsed. However,
this method returns the security name of the caller only. If you need
to know more than the security name, call the getCallerList method
and retrieve the first entry in the String array. This entry provides
all the caller information.
The output, for example, is: jsmith.
The following code sample retrieves the security name
of the first authenticated caller using the getFirstCaller API:
String first_caller = null;
// If security is disabled on this application server, do not bother checking
if (com.ibm.websphere.security.WSSecurityHelper.isServerSecurityEnabled())
{
try
{
// Gets the first caller
first_caller = com.ibm.websphere.security.WSSecurityHelper.getFirstCaller();
// Prints out the caller name
System.out.println("First caller: " + first_caller);
}
catch (Exception e)
{
// Performs normal exception handling for your application
}
}
- Obtain the name of the first application server for a request,
using the getFirstServer method.
Whenever you want to
know what the first application server is for this request, call the
getFirstServer method directly.
The output, for example, is: myManager:node1:server1.
The following code sample retrieves the name of the first
application server using the getFirstServer API:
String first_server = null;
// If security is disabled on this application server, do not bother checking
if (com.ibm.websphere.security.WSSecurityHelper.isServerSecurityEnabled())
{
try
{
// Gets the first server
first_server = com.ibm.websphere.security.WSSecurityHelper.getFirstServer();
// Prints out the server name
System.out.println("First server: " + first_server);
}
catch (Exception e)
{
// Performs normal exception handling for your application
}
}
- Add custom attributes to the default propagation token,
using the addPropagationAttribute API.
You can add custom
attributes to the default propagation token for application usage.
This token follows the request downstream so that the attributes are
available when needed. When you use the default propagation token
to add attributes, you must understand the following issues:
- Adding information to the propagation token affects CSIv2 session
caching. Add information sparingly between remote requests.
- After you add information with a specific key, the information
cannot be removed.
- You can add as many values to a specific key as you need. However,
all of the values must be available from a returned String array in
the order that they were added.
- The propagation token is available only on servers where propagation
and security are enabled.
- The Java 2 Security javax.security.auth.AuthPermission wssecurity.addPropagationAttribute
attribute is needed to add attributes to the default propagation token.
- An application cannot use keys that begin with either com.ibm.websphere.security
or com.ibm.wsspi.security. These prefixes are reserved for system
usage.
The following code
sample shows how to use the addPropagationAttribute API:
// If security is disabled on this application server,
// do not check the status of server security
if (com.ibm.websphere.security.WSSecurityHelper.isServerSecurityEnabled())
{
try
{
// Specifies the key and values
String key = "mykey";
String value1 = "value1";
String value2 = "value2";
// Sets key, value1
com.ibm.websphere.security.WSSecurityHelper.
addPropagationAttribute (key, value1);
// Sets key, value2
String[] previous_values = com.ibm.websphere.security.WSSecurityHelper.
addPropagationAttribute (key, value2);
// Note: previous_values should contain value1
}
catch (Exception e)
{
// Performs normal exception handling for your application
}
}
- Obtain your custom attributes with the get PropagationAttributes
API.
Custom attributes are added to the default propagation
token using the addPropagationAttribute API. Retrieve these attributes
using the getPropagationAttributes API. This token follows the request
downstream so the attributes are available when needed. When you use
the default propagation token to retrieve attributes, you must understand
the following issues:
- The propagation token is available only on servers where propagation
and security are enabled.
- The Java 2 Security javax.security.auth.AuthPermission "wssecurity.getPropagationAttributes"
permission is needed to retrieve attributes from the default propagation
token.
See Adding
custom attributes to the default PropagationToken to add attributes
using the addPropagationAttributes API.
The output, for example,
is:
Value[0] = value1
Value[1] = value2
The following
code sample shows how to use the getPropagationAttributes API:
// If security is disabled on this application server, do not bother checking
if (com.ibm.websphere.security.WSSecurityHelper.isServerSecurityEnabled())
{
try
{
String key = "mykey";
String[] values = null;
// Sets key, value1
values = com.ibm.websphere.security.WSSecurityHelper.
getPropagationAttributes (key);
// Prints the values
for (int i=0; i<values.length; i++)
{
System.out.println("Value[" + i + "] = " + values[i]);
}
}
catch (Exception e)
{
// Performs normal exception handling for your application
}
}
- Modify the propagation token factory configuration to use
a token factory other than the default token factory.
When
WebSphere Application Server generates a default propagation token,
the Application Server utilizes the TokenFactory class that is specified
using the com.ibm.wsspi.security.token.propagationTokenFactory property.
The
default token factory that is specified for this property is called
com.ibm.ws.security.ltpa.AuthzPropTokenFactory. This token factory
encodes the data in the propagation token and does not encrypt the
data. Because the propagation token typically flows over CSIv2 using
Secure Sockets Layer (SSL), encrypting the token is not required.
However, if you need additional security for the propagation token,
you can associate a different token factory implementation with this
property to get encryption. For example, if you choose to associate
the com.ibm.ws.security.ltpa.LTPAToken2Factory token factory with
this property, the token is AES encrypted. However, you need to weigh
the performance impacts against your security needs. Adding sensitive
information to the propagation token is a good reason to change the
token factory implementation to something that encrypts rather than
just encodes.
To modify this property using the administrative
console, complete the following steps:
- Open the administrative console.
- Click Security > Secure administration,
applications, and infrastructure.
- Under Additional properties, click Custom properties.
- Perform your own signing and encryption of the default
propagation token.
If you want to perform your own signing
and encryption of the default propagation 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 choose to use the Lightweight Third
Party Authentication (LTPA) keys and have them pass 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,
available through a link on the front page of the information center,
for more information on implementing your own custom token factory.
- Associate your token factory with the default propagation
token.
- Open the administrative console.
- Under Additional properties, click Custom
properties.
- Locate the com.ibm.wsspi.security.token.propagationTokenFactory
property and verify that the value of this property matches your custom
token factory implementation.
- 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.
Verify that your implementation
classes are located in the ${USER_INSTALL_ROOT}/classes directory
so that the WebSphere Application Server class loader can load the
classes.
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.