After a custom Java object is added into the Subject, WebSphere
Application Server serializes the object on the sending server, deserializes
the object on the receiving server, and adds the object back into the Subject
downstream. However, some requirements exist for this process to occur successfully.
For more information on the JAAS programming model, see the JAAS information
provided in
Security: Resources for learning.
Important: Whenever you plug a custom login module
into the login infrastructure of WebSphere Application Server, make sure that
the code is trusted. When you put the classes together in a Java archive (JAR)
file and add the file to the
app_server_root/lib/ext/ directory,
the login module has Java 2 Security AllPermissions permissions . It is recommended
that you add your login module and other infrastructure classes into any private
directory. However, you must modify the
install_root/properties/server.policy file
to make sure that your private directory, Java archive (JAR) file, or both
have the permissions required to run the application programming interfaces
(API) that are called from the login module. Because the login module might
be run after the application code on the call stack, you might add doPrivileged
code so that you do not need to add additional properties to your applications.
Important: Whenever you plug a custom login module
into the login infrastructure of WebSphere Application Server, make sure that
the code is trusted. When you add the login module into the
profile_root/classes directory,
the login module has Java 2 Security AllPermissions permissions. For more
information, see
Creating a classes subdirectory in your profile for custom classes.
However, because the login module might be run after the application code
on the call stack, you might add doPrivileged code so that you do not need
to add additional properties to your applications.
The following
code sample shows how to add doPrivileged code. For information on what to
do during initialization, login and commit, see
Developing custom login modules for a system login configuration.
public customLoginModule()
{
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map sharedState, Map options)
{
}
public boolean login() throws LoginException
{
// Construct callback for the WSTokenHolderCallback so that you
// can determine if
// your custom object has propagated
Callback callbacks[] = new Callback[1];
callbacks[0] = new WSTokenHolderCallback("Authz Token List: ");
try
{
_callbackHandler.handle(callbacks);
}
catch (Exception e)
{
throw new LoginException (e.getLocalizedMessage());
}
// Checks to see if any information is propagated into this login
List authzTokenList = ((WSTokenHolderCallback) callbacks[1]).
getTokenHolderList();
if (authzTokenList != null)
{
for (int i = 0; i< authzTokenList.size(); i++)
{
TokenHolder tokenHolder = (TokenHolder)authzTokenList.get(i);
// Look for your custom object. Make sure you use
// "startsWith"because there is some data appended
// to the end of the name indicating in which Subject
// Set it belongs. Example from getName():
// "com.acme.CustomObject (1)". The class name is
// generated at the sending side by calling the
// object.getClass().getName() method. If this object
// is deserialized by WebSphere Application Server,
// then return it and you do not need to add it here.
// Otherwise, you can add it below.
// Note: If your class appears in this list and does
// not use custom serialization (for example, an
// implementation of the Token interface described in
// the Propagation Token Framework), then WebSphere
// Application Server automatically deserializes the
// Java object for you. You might just return here if
// it is found in the list.
if (tokenHolder.getName().startsWith("com.acme.CustomObject"))
return true;
}
}
// If you get to this point, then your custom object has not propagated
myCustomObject = new com.acme.CustomObject();
myCustomObject.put("mykey", "mydata");
}
public boolean commit() throws LoginException
{
try
{
// Assigns a reference to a final variable so it can be used in
// the doPrivileged block
final com.acme.CustomObject myCustomObjectFinal = myCustomObject;
// Prevents your applications from needing a JAAS getPrivateCredential
// permission.
java.security.AccessController.doPrivileged(new java.security.
PrivilegedExceptionAction()
{
public Object run() throws java.lang.Exception
{
// Try not to add a null object to the Subject or an object
// that already exists.
if (myCustomObjectFinal != null && !subject.getPrivateCredentials().
contains(myCustomObjectFinal))
{
// This call requires a special Java 2 Security permission,
// see the JAAS application programming interface (API)
// documentation.
subject.getPrivateCredentials().add(myCustomObjectFinal);
}
return null;
}
});
}
catch (java.security.PrivilegedActionException e)
{
// Wraps the exception in a WSLoginFailedException
java.lang.Throwable myException = e.getException();
throw new WSLoginFailedException (myException.getMessage(), myException);
}
}
// Defines your login module variables
com.acme.CustomObject myCustomObject = null;
}