To authenticate a UsernameToken with a caller part without
accessing the WebSphere Application Server registry, you can replace
the authentication method of the UsernameToken consumer and configure
the caller to use an alternative Java Authentication
and Authorization Service (JAAS) login configuration.
About this task
This information applies only to Java API
for XML-based RPC (JAX-RPC) web services.
By default, the default
JAAS login module that is used with the web Services Security UsernameToken
consumer, UsernameLoginModule, always validates the user name and
password that are contained within the token against the WebSphere
registry. You can configure a custom property to circumvent this registry
check. When a caller part is added to the WS-Security constraints
for a service provider, the user name and password that are contained
in the UsernameToken are also validated against the WebSphere registry.
This validation occurs in the com.ibm.ws.security.server.lm.ltpaLoginModule module
that is part of the system.DEFAULT Java Authentication
and Authorization Service (JAAS)configuration stack, as shown in the
following example.
com.ibm.ws.security.server.lm.ltpaLoginModule
com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule
The
WebSphere Application Server WS-Security run time does not support
the use of a JAAS configuration for the caller part that does not
include these two login modules. However, you can add your own custom
login modules to this JAAS configuration stack.
To use a UsernameToken
with a caller part without accessing the WebSphere Application Server
registry, you must prevent both the UsernameLoginModule and ltpaLoginModule
modules from accessing the registry.
Note: When a UsernameToken is
added to a provider application using the wizard in an application
developer, it automatically adds a caller part for the UsernameToken.
A caller part is only needed if you want the identity from the UsernameToken
to be on the thread of execution. If your application does not require
the identity from the UsernameToken to be on the thread of execution,
then you do not need the caller part and can remove it. The caller
part is configured in the deployment descriptor extensions and can
be accessed only with an application developer
Refer
to "Configuring the caller in consumer security constraints" topic
in the IBM Rational Application Developer information center.
- To prevent the UsernameLoginModule module from accessing
the registry, add the com.ibm.wsspi.wssecurity.auth.module.UsernameLoginModule.disableUserRegistryCheck custom
property to the JAAS configuration for the UsernameToken consumer.
You can add this custom property in one of two ways:
Avoid trouble: The update to the wssecurity.UsernameToken JAAS
configuration causes all users of this JAAS configuration on the application
server to not check the registry. If you do not want this behavior,
create a new JAAS configuration or use the method to update the UsernameToken
consumer
gotcha
To add the custom property to the com.ibm.wsspi.wssecurity.auth.module.UsernameLoginModule module
in the wssecurity.UsernameToken JAAS configuration:
- Click Security > Global security.
- Under Authentication, click Java
Authentication and Authorization Service > System logins.
- Select wssecurity.UsernameToken.
- Select com.ibm.wsspi.wssecurity.auth.module.UsernameLoginModule.
- Add the following custom property: com.ibm.wsspi.wssecurity.auth.module.UsernameLoginModule.disableUserRegistryCheck=true.
- Click OK.
- Restart the application server to reload the updated JAAS configuration.
To add the custom property to the application's token consumer,
perform the following steps:
- Click Applications > Application Types > WebSphere
enterprise applications > (providerAppName) > Manage Modules > (moduleName)
> Web services: Server security bindings.
- Under Request consumer (receiver) binding,
click Edit custom > Token consumers.
- Select your UsernameToken consumer.
- Click JAAS configuration > Properties > New.
- Add the following custom property: com.ibm.wsspi.wssecurity.auth.module.UsernameLoginModule.disableUserRegistryCheck=true.
- Click OK.
- Click Save.
- Restart the application.
Note: If your UsernameToken consumer's name looks like 'Token_123'
and is not selectable, then the application developer that you used
to add your security constraints failed to give a name to your token
consumer in the deployment descriptor. As an alternative, you can
perform one of the following two options.
- Add the property to the security JAAS configuration as described
in step 1.
- Edit the deployment descriptor bindings in your application project
using an application developer.
Refer to the "Configuring the security token requirement in consumer
security constraints" topic in the IBM Rational Application Developer
information center.
- Develop a JAAS login module that stacks above com.ibm.ws.security.server.lm.ltpaLoginModule.
The following example shows sample code for the JAAS login module:
package test.tokens;
import java.util.Map;
import java.util.Hashtable;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import com.ibm.wsspi.wssecurity.auth.token.UsernameToken;
import com.ibm.wsspi.security.token.AttributeNameConstants;
public class MyAuthLoginModule implements LoginModule {
private Map _sharedState = null;
private CallbackHandler _callbackHandler = null;
Subject _subject = null;
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this._sharedState = sharedState;
this._callbackHandler = callbackHandler;
this._subject = subject;
}
public boolean login() throws LoginException {
//For the sake of readability, this login module does not
//protect against all NPE's
String username = null;
char [] password = null;
NameCallback nameCallback = null;
PasswordCallback passwordCallback = null;
//Get the username and password from callbacks that
//the ws-security runtime set up
Callback[] callbacks = new Callback[2];
callbacks[0] = nameCallback = new NameCallback("Username: ");
callbacks[1] = passwordCallback = new PasswordCallback("Password: ", false);
try {
_callbackHandler.handle(callbacks);
} catch ( Exception e ) {
throw new LoginException("Unable to process callbacks");
}
if (nameCallback != null) {
username = nameCallback.getName();
}
if (passwordCallback != null) {
char tmp[] = passwordCallback.getPassword();
if (tmp != null && tmp.length != 0) {
password = new char[tmp.length];
System.arraycopy(tmp, 0, password, 0, tmp.length);
}
}
if (username == null) {
throw new LoginException("Unable to obtain username");
}
//If you will be validating the username and password,
//validate it here
Hashtable customProperties = (Hashtable)_sharedState.get(AttributeNameConstants.WSCREDENTIAL_PROPERTIES_KEY);
if (customProperties == null) {
customProperties = new Hashtable();
_sharedState.put(AttributeNameConstants.WSCREDENTIAL_PROPERTIES_KEY, customProperties);
}
// Default realm is used here, but any trusted realm can be used
String uid = "defaultWIMFileBasedRealm/" + username;
customProperties.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, uid)
// SECURITYNAME will be the principal name
customproperties.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, username);
return true;
}
public boolean logout() throws LoginException {
return false;
}
}
- Create a JAAS login configuration.
- In the administrative console, select Security
> Global security.
- Under Authentication, select Java Authentication
and Authorization Service > System logins.
- Click New, and under Aliases,
enter test.auth.jaxrpcunt.
- Add the JAAS login modules. You must add the following
login modules in the order shown:
test.tokens.MyAuthLoginModule
Note: The
name of this module must match the JAAS login module that you developed.
com.ibm.ws.security.server.lm.ltpaLoginModule
com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule
For
each login module:
- Under JAAS login modules, click New.
- Under Module class name, enter the name
of the login module.
- For test.tokens.MyAuthLoginModule only, select Use
login module proxy.
- Click OK.
- Click OK, then Save.
- Restart the application server to apply the JAAS configuration
changes.
- Configure your caller part to use the new JAAS configuration.
You can configure your caller part by using only an application developer.
Refer to "Configuring the caller in consumer security constraints"
topic in the IBM Rational Application Developer information center.
- Add the following custom property to the caller part for the UsernameToken: com.ibm.wsspi.wssecurity.Caller.assertionLoginConfig=system.test.auth.jaxrpcunt.
- Save the deployment descriptor
- Redeploy the application to the server
- Test the service.