You can dynamically pass a username and password to the
LTPA token generator, LTPAGenerateLoginModule, when using WSS SPIs.
However, if you must use policy sets and bindings, you cannot do
this in a standard configuration because both the callback handler,
and the username and password in the callback handler are fixed values.
You can use policy sets and bindings to create dynamic Kerberos tokens
if a custom JAAS login module is used.
Before you begin
If you create a custom JAAS login module, or add a UsernameToken
to the client's request context, you can customize the username and
password that the LTPA token generator uses when creating an LTPA
token. You can also customize the token by directly setting the token
bytes that the LTPA token generator uses. Setting the token bytes
is useful when an application developer wants to write code to obtain
the LTPA token from the HTTP header of an inbound request and place
it into the Security header of an outbound SOAP message.
About this task
The GenericSecurityTokenFactory provides SPIs that you
can use to create a token that the LTPAGenerateLoginModule can use
to customize the LTPA token that this module generates. These SPIs
enable you to use dynamic usernames and passwords, or to directly
set the token bytes, which are capabilities that the callback handler
does not provide.
The following procedure shows how to use the
stacked JAAS login module method to customize the username and password
or token bytes. After you complete this procedure, you can also place
the newly created token on the client's request context. For more
information on how to place a token on the client's request context,
refer to the following constants in com.ibm.wsspi.wssecurity.core.Constants
Javadoc:
- com.ibm.wsspi.wssecurity.token.tokenHolder
- com.ibm.wsspi.wssecurity.token.enableCaptureTokenContext
Procedure
- Create the dynamic token.
Complete one of
the following substeps.
- To customize the username and password, create a simple
UsernameToken.
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
...
GenericSecurityTokenFactory gstFactory = GenericSecurityTokenFactory.getInstance();
UsernameToken myUnt = gstFactory.getSimpleUsernameToken("myUsername", "myPassword".toCharArray());
- To customize the token bytes, create a simple BinarySecurityToken
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
import com.ibm.websphere.wssecurity.wssapi.token.BinarySecurityToken;
import com.ibm.websphere.wssecurity.wssapi.WSSUtilFactory;
...
GenericSecurityTokenFactory gstFactory = GenericSecurityTokenFactory.getInstance();
WSSUtilFactory utilFactory = WSSUtilFactory.getInstance();
//callbackHandler is obtained from the initialize method in the Login Module
Map reqHeaders = utilFactory.getHTTPRequestHeaders(callbackHandler);
//getLtpaHeaderBytes is a method written by you to find the header that
//has the LTPA token in it in the header list, then return the encoded
//bytes out of the header.
String encodedBytes = getLtpaHeaderBytes(reqHeaders);
byte [] decodedBytes = utilFactory.decode(encodedBytes);
BinarySecurityToken bst = factory.getSimpleBinarySecurityToken(com.ibm.websphere.wssecurity.wssapi.token.LTPAv2Token, decodedBytes);
- Create a JAAS login module.
package test.tokens;
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
import com.ibm.websphere.wssecurity.wssapi.token.BinarySecurityToken;
public class MyUntCustomLoginModule implements LoginModule {
//For the sake of readability, this login module does not
//protect against all NPE's
private Map _sharedState;
private Map _options;
private CallbackHandler _handler;
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this._handler = callbackHandler;
this._sharedState = sharedState;
this._options = options;
}
public boolean login() throws LoginException {
GenericSecurityTokenFactory factory = null;
try {
factory = GenericSecurityTokenFactory.getInstance();
} catch (Exception e) {
throw new LoginException(e.toString());
}
//code to create the BinarySecurityToken can be used
//here instead of the simple UsernameToken
UsernameToken unt = factory.getSimpleUsernameToken("myUsername", "myPassword".toCharArray());
factory.putGeneratorTokenToSharedState(this._sharedState, unt);
return true;
}
//implement the rest of the methods required by the
//LoginModule interface
}
- Create a new JAAS login configuration.
- In the administrative console, select Security->Global
security.
- Under Authentication, select Java Authentication
and Authorization Service.
- Select System logins.
- Create the generator with the custom module first.
- Click New, and then specify Alias
= test.generate.ltpa.
- Click New, and then specifyModule
class name = test.tokens.MyUntCustomLoginModule.
- Select Use login module proxy .
- Click OK.
- Click New, and then select com.ibm.ws.wssecurity.wssapi.token.impl.LTPAGenerateLoginModule.
- Click OK.
- Click JAAS - System logins.
- Configure your LTPA token generator to use the new JAAS
configuration.
- Open your bindings configuration that you want to change.
In the administrative console, select WS-Security
> Authentication and protection.
- Under Authentication tokens, select the outbound LTPA
token that you want to change.
- Select JAAS login = test.generate.ltpa.
- Click Save.
- Restart the application server to apply the JAAS configuration
changes.
- Test your service.