192 lines
12 KiB
HTML
192 lines
12 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
|
<html>
|
||
|
<head>
|
||
|
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<LINK rel="stylesheet" type="text/css" href="../../../rzahg/ic.css">
|
||
|
|
||
|
<title>Validating a pluggable token</title>
|
||
|
</head>
|
||
|
|
||
|
<BODY>
|
||
|
<!-- Java sync-link -->
|
||
|
<SCRIPT LANGUAGE="Javascript" SRC="../../../rzahg/synch.js" TYPE="text/javascript"></SCRIPT>
|
||
|
|
||
|
<h6><a name="wssecplugtokver"></a>Validating a pluggable token</h6>
|
||
|
|
||
|
<p>This topic describes how to develop a Java Authentication and Authorization Service (JAAS) login module to authenticate the security token of an incoming request. The pluggable token is based on the JAAS programming model. You can develop and configure custom JAAS Login modules to authenticate custom security tokens.</p>
|
||
|
|
||
|
<p>See <a href="wsseccfplugtoken.htm">Configure a pluggable token</a> for information about configuring the pluggable token authentication for a request receiver.</p>
|
||
|
|
||
|
<p><strong>Standard login mapping configuration</strong></p>
|
||
|
<p>WebSphere Application Server - Express provides default implementations and configurations of the following login mappings:</p>
|
||
|
|
||
|
<ul>
|
||
|
<li><p><strong>BasicAuth</strong>
|
||
|
<br>BasicAuth is used to authenticate both a user name and a password.</p></li>
|
||
|
|
||
|
<li><p><strong>Signature</strong>
|
||
|
<br>Signature is used to map the distinguished name (DN) of the certificate to a JAAS Subject.</p></li>
|
||
|
|
||
|
<li><p><strong>IDAssertion</strong>
|
||
|
<br>IDAssertion is used to map a trusted identity to a JAAS Subject for identity assertion.</p></li>
|
||
|
|
||
|
<li><p><strong>LTPA</strong>
|
||
|
<br>Lightweight Third-party Authentication (LTPA) is used to authenticate LTPA security tokens. The value type of the LTPA is http://www.ibm.com/websphere/appserver/tokentype/5.0.2/LTPA</p></li>
|
||
|
</ul>
|
||
|
|
||
|
<p>However, because the token is pluggable, you can can provide your own implementation. The token value is optional for the BasicAuth, Signature, and IDAssertion authentication methods. However, the token value is required by other types of authentication methods, including LTPA and the pluggable token. It is used to validate against the value type of binary security token (<wsse:BinarySecurityToken@ValueType>) and against the namespace for XML-based token. Therefore, the request sender must have the correct value type configured and inserted into the security tokens.</p>
|
||
|
|
||
|
<p><strong>Developing a JAAS Login Module</strong></p>
|
||
|
<p>The following figure shows the relationship between the login mapping configuration and the pluggable token validation.</p>
|
||
|
|
||
|
<p><strong>Figure 1: Token validation</strong></p>
|
||
|
<p><img src="rzaiz613.gif" width="531" height="337" alt="Token validation"></p>
|
||
|
|
||
|
<p>The com.ibm.wsspi.wssecurity.auth.callback.CallbackHandlerFactory interface is a factory that is used to create an instance of the javax.security.auth.callback.CallbackHandler interface. For more information, see the <a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/security/auth/callback/CallbackHandler.html" target="_">Javadoc</a> <img src="www.gif" width="19" height="15" alt="Link outside Information Center"> (http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/security/auth/callback/CallbackHandler.html). The various set() methods are used by the Web services security run time to pass various security tokens (<wsse:UsernameToken>, <BinarySecurityToken>, and XML-based security token and properties from the login binding) to the implementation, which can pass the security tokens to the new callback handler instance. The properties defined for the CallbackHandlerFactory in the login mapping are passed to the implementation through the com.ibm.wsspi.wssecurity.auth.callback.CallbackHandlerFactory.init() method.</p>
|
||
|
|
||
|
<p>WebSphere Application Server - Express provides a default implementation of the CallbackHandlerFactory interface, which is called com.ibm.wsspi.wssecurity.auth.callback.WSCallbackHandlerFactoryImpl. The default implementation creates a callback handler that can handle the following javax.security.callback.Callback implementation classes:</p>
|
||
|
|
||
|
<ul>
|
||
|
<li><strong>javax.security.auth.callback.NameCallback</strong> and <strong>javax.security.auth.callback.PasswordCallback</strong>
|
||
|
<br>The JAAS login module uses these callbacks to obtain basic authentication information. If the Simple Object Access Protocol (SOAP) header contains <wsse:UsernameToken>, the following actions occur:
|
||
|
<ol>
|
||
|
<li>The Web services security run time passes the user name and password to the CallbackHandlerFactory implementation.</li>
|
||
|
<li>The CallbackHandlerFactory passes the information to the CallbackHandler implementation. The CallbackHandler implementation can set the user name and password using the javax.security.auth.callback.NameCallback.getName() and javax.security.auth.callback.PasswordCallback.getPassword() methods respectively.</li>
|
||
|
</ol><p></p></li>
|
||
|
|
||
|
|
||
|
<li><strong>com.ibm.websphere.security.auth.callback.WSCredTokenCallbackImpl</strong> or <strong>com.ibm.wsspi.wssecurity.auth.callback.BinaryTokenCallback</strong>
|
||
|
<br>The JAAS login module can use either of these implementations to obtain the token byte. If the SOAP header contains <wsse:BinarySecurityToken>, the following actions occur:
|
||
|
<ol>
|
||
|
<li>The Web services security run time passes the token byte to the CallbackHandlerFactory implementation.</li>
|
||
|
<li>The CallbackHandlerFactory implementation passed the token byte to the CallbackHandler iplementation. The CallbackHandler implementation returns from com.ibm.wsspi.wssecurity.auth.callback.WSCallbackHandlerFactoryImpl set the token byte to both of the above Callbacks. (WSCallbackHandlerFactoryImpl passes tokens to CallbackHandler and CallbackHandler passes the tokens to the JAAS Login Module using Callbacks.) The JAAS Login Module can obtain the token byte using either com.ibm.websphere.security.auth.callback.WSCredTokenCallbackImpl.getCredToken() or com.ibm.wsspi.wssecurity.auth.callback.BinaryTokenCallback.getCredToken().</li>
|
||
|
</ol><p></p></li>
|
||
|
|
||
|
<li><p><strong>com.ibm.wsspi.wssecurity.auth.callback.XMLTokenReceiverCallback</strong>
|
||
|
<br>The JAAS login module uses this callback to obtain the XML-based token. If the SOAP header contains a XML-based token, the Web services security run time passes the token as org.w3c.dom.Element and the whole SOAP message as org.w3c.dom.Document to CallbackHandlerFactory implementation. The JAAS login module can obtain the XML-based token and the whole SOAP message using the com.ibm.wsspi.wssecurity.auth.callback.XMLTokenReceiverCallback.getXMLToken() and com.ibm.wsspi.wssecurity.auth.callback.XMLTokenReceiverCallback.getSOAPMessage() methods respectively.</p></li>
|
||
|
|
||
|
<li><p><strong>com.ibm.wsspi.wssecurity.auth.callback.PropertyCallback</strong>
|
||
|
<br>If there are name and value pairs defined in the login mapping, the Web services security run time passes these pairs as java.util.Map to the CallbackHandlerFactory implementation, which, in turn, passes the pairs to the CallbackHandler implementation. The JAAS login module can obtain these properties by calling com.ibm.wsspi.wssecurity.auth.callback.PropertyCallback.getProperties()method.</p></li>
|
||
|
</ul>
|
||
|
|
||
|
<p><strong>com.ibm.wsspi.wssecurity.auth.module.WSSecurityMappingModule</strong></p>
|
||
|
<p>WebSphere Application Server - Express also provides a default JAAS login module that you can use to map an identity to a principal and a credential. WebSphere Application Server - Express then can use the identity. The JAAS Login Module is called com.ibm.wsspi.wssecurity.auth.module.WSSecurityMappingModule. After the custom JAAS Login Module validates or authenticates the security token, the WSSecurityMappingModule can be used to map the identity to principal and credential format that can be used WebSphere Application Server - Express. You can configure the WSSecurityMappingModule module as the last JAAS login module in the JAAS login configuration using the stackable login module of JAAS. For more information on configuring a JAAS login, see <a href="../sec/seccjaas.htm">Configure JAAS login</a> in the <em>Security</em> topic.</p>
|
||
|
|
||
|
<p>The WSSecurityMappingModule.login() method looks for the identity using the com.ibm.wsspi.wssecurity.Constants.DN key from the shared state map (java.util.Map) of a JAAS login context. The shared state map is passed to the JAAS login module by the javax.security.auth.spi.LoginModule.initialize() method. After the credential is successfully created by the WSSecurityMappingModule.login() method, the WSSecurityMappingModule saves it in the shared state map by using the com.ibm.wsspi.wssecurity.Constants.WSCredential key. The other JAAS Login Modules can get the credential into their commit method. The credential is removed in the abort or commit method of the WSSecurityMappingModule.</p>
|
||
|
|
||
|
<p><strong>Sample</strong></p>
|
||
|
<p>The following sample code is a sample JAAS login module implementation that is used to validate the <wsse:BinarySecurityToken> element. The error handling was removed for clarity.</p>
|
||
|
|
||
|
<pre>import javax.security.auth.*;
|
||
|
import javax.security.auth.callback.*;
|
||
|
import javax.security.auth.spi.*;
|
||
|
import com.ibm.websphere.security.auth.callback.*;
|
||
|
import java.util.*;
|
||
|
import javax.security.auth.login.*;
|
||
|
import com.ibm.websphere.security.cred.*;
|
||
|
import com.ibm.wsspi.wssecurity.auth.callback.*;
|
||
|
|
||
|
public class MyBSTLoginModule implements LoginModule {
|
||
|
private Subject subject;
|
||
|
private CallbackHandler callbackHandler;
|
||
|
private Map sharedState;
|
||
|
private Map options;
|
||
|
|
||
|
private boolean succeeded = false;
|
||
|
private boolean commitSucceeded = false;
|
||
|
|
||
|
private byte[] token = null;
|
||
|
private Map properties = null;
|
||
|
private WSCredential credential = null;
|
||
|
|
||
|
public MyBSTLoginModule() {
|
||
|
}
|
||
|
|
||
|
public void initialize(Subject subject, CallbackHandler callbackHandler,
|
||
|
Map sharedState, Map options) {
|
||
|
this.subject = subject;
|
||
|
this.callbackHandler = callbackHandler;
|
||
|
this.sharedState = sharedState;
|
||
|
this.options = options;
|
||
|
}
|
||
|
|
||
|
public boolean login() throws LoginException {
|
||
|
if (callbackHandler == null)
|
||
|
throw new LoginException("No CallbackHandler");
|
||
|
|
||
|
succeeded = false;
|
||
|
|
||
|
Callback[] callbacks = new Callback[2];
|
||
|
callbacks[0] = new WSCredTokenCallbackImpl("Cred token: ");
|
||
|
callbacks[1] = new PropertyCallback(null);
|
||
|
|
||
|
try {
|
||
|
callbackHandler.handle(callbacks);
|
||
|
token = ((WSCredTokenCallbackImpl) callbacks[0]).getCredToken();
|
||
|
// get the property in Login Mapping
|
||
|
properties = ((PropertyCallback) callbacks[1]).getProperties();
|
||
|
} catch (java.io.IOException ioe) {
|
||
|
throw new LoginException(ioe.toString());
|
||
|
} catch (UnsupportedCallbackException uce) {
|
||
|
throw new LoginException(uce.getCallback().toString());
|
||
|
}
|
||
|
|
||
|
// validate the token and extract the id from the token
|
||
|
succeeded = validate(token);
|
||
|
String id = extractId(token);
|
||
|
// put the identity in shared state
|
||
|
sharedState.put(com.ibm.wsspi.wssecurity.Constants.WSSECURITY_DN, id);
|
||
|
|
||
|
// ....
|
||
|
|
||
|
return succeeded;
|
||
|
}
|
||
|
|
||
|
public boolean commit() throws LoginException {
|
||
|
commitSucceeded = false;
|
||
|
|
||
|
if (succeeded == true) {
|
||
|
// set the custom token in the subject ....
|
||
|
// to get the websphere credential
|
||
|
credential = (WSCredential) sharedState.get(com.ibm.wsspi.wssecurity.Constants.WSSECURITY_CRED);
|
||
|
// ....
|
||
|
commitSucceeded = true;
|
||
|
} else {
|
||
|
// error;
|
||
|
}
|
||
|
|
||
|
return commitSucceeded;
|
||
|
}
|
||
|
|
||
|
private boolean validate(byte[] t) {
|
||
|
// validate token
|
||
|
// ....
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private String extractId(byte[] t) {
|
||
|
// extract token id
|
||
|
// ....
|
||
|
return ...;
|
||
|
}
|
||
|
|
||
|
public boolean abort() throws LoginException {
|
||
|
cleanup();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public boolean logout() throws LoginException {
|
||
|
cleanup();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private void cleanup() {
|
||
|
succeeded = false;
|
||
|
commitSucceeded = false;
|
||
|
// cleanup
|
||
|
}
|
||
|
}</pre>
|
||
|
|
||
|
</body>
|
||
|
</html>
|