Leveraging Trust Association Interceptors (TAIs)
Use of TAI is considered an advanced topic and should not be required for most applications. The target audience for TAI support for WebSphere sMash is for current users of TAI who want to leverage existing TAI implementations. If you want to extend or implement your own security handlers, see the Extending security section that provides information about the preferred method for extending security in WebSphere sMash. WebSphere sMash provides an extensible framework for single sign on (SSO) with external authentication services such as reverse proxies through trust associations. When trust association is enabled, WebSphere sMash is not required to authenticate a user if a request arrives from a trusted source that has already performed authentication.
The following sections provide information regarding the conversion of existing TAI implementations designed for the J2EE platform (such as WebSphere Application Server) to WebSphere sMash. For a good overview of one of the more common TAI implementations, see the Tivoli Access Manager Trust Association Interceptor developerWorks article.
Working with existing TAIs in WebSphere sMash
Most security providers set security context in HTTP request headers and TAIs retrieve that information from the HttpServletRequest headers. There are two options for calling TAI implementations from WebSphere sMash.
- Rewriting the existing TAI implementation (preferred) to leverage the Global context instead of the
HttpServletRequestandHttpServletResponseobjects that are more typically used. While this could be time consuming, it is the suggested method for implementing TAI implementations for WebSphere sMash.
- Creating a a bridge between what is in the global context and the
HttpServletRequestandHttpServletResponseclasses required by TAI. This is an option if there are many TAI implementations already in existence. Because WebSphere sMash is based on J2SE and not J2EE, this is not included as part of WebSphere sMash but this could be done by a TAI implementor.
WebSphere sMash security provides an extension point for registering a TAIExtensionHandler object as an event handler. The TAI extension is called by the security component when the onSecure event runs and TAI is configured for that resource.
Implementation of TAI extension handler
The TAI extension handler must be implemented based on the following rules:
- All must be implement onTAIValidateRequest method.
- An appropriate HTTP status code must be set to
GlobalContextwith key/request/status. - An authenticated user must be set to
GlobalContextasjava.util.Set<java.security.Principal>with key/event/taiValidatedsetOfPrincipals. If the handler can obtain group names for an authenticated user, they should be included in the set of principals. - Security context must be converted between
GlobalContextand a context container that a TAI implementation uses includingjavax.servlet.http.HttpServletRequest/Response.
The following example shows pseudo code for an example SecurityContextHandler :
public class TestSecurityContextHandler {
// wrapper class for the GlobalContext related request keys
private class CustomHttpServletRequest implements HttpServletRequest{
public CustomHttpServletRequest(){
}
public String getHeader (String headerValue){
return GlobalContext.zget (Request.Headers.in +"/" +headerValue);
}
}
// wrapper class for the GlobalContext related response keys
private class CustomHttpServletResponse implements HttpServletResponse{
public CustomHttpServletResponse(){
}
public void setStatus(int status){
GlobalContext.zput(Request.status,status);
}
}
//Event Handler Method
public void onTAIValidateRequest() {
//Get security contexts from GlobalContext
// and put them to an appropriate context container like javax.servlet.http.HttpRequestContext
HttpServletRequest httpServletRequestImpl = new CustomHttpServletRequest();
HttpServletResponse httpServletResponseImpl = new CustomHttpServletResponse();
String authHeaderVal = httpServletRequestImpl.getHeader(....,....);
//Validate the request with 3rd party Security Provider
boolean validateResult = taiImpl.validateRequestWith3rdPartySecurityProvider( httpServletRequestImpl , httpServletResponseImpl );
if(validateResult){
//Validation succeeds
//Add a user principal to a set of principals
Set<java.security.Principal> principals = new HashSet<java.security.Principal>();
principals.add(userPrincipal);
//If group principals can be obtain, set them to the set of principals
if(groupPrincipals != null){
principals.addAll(groupPrincipals);
}
//Set the set of principals to GlobalContext
GlobalContext.zput("/event/taiValidatedSetOfPrincipals", principals);
//Http status "200" should be set by application.
//So , when validation succeeds, no status code is set
}else{
//For failed validation result, set 403 on the HttpServletResponse
httpServletResponseImpl.setStatus(HttpURLConnection.HTTP_FORBIDDEN);
}
}
}
Authorization
Custom authorization implementation is supported by WebSphere sMash, as long as it is registered as an authorize event handler. WebSphere sMash security authorizes the request using the user name and group names in GlobalContext. If there are no group names in GlobalContext, WebSphere sMash security tries to obtain group names for the user from the user service registry. LDAP is most common user registry and it is easily accessible for both trusted servers and WebSphere sMash.
Configuring zero.config
The following example shows how zero.config is used for third party token validation:
/config/handlers += [{
"events" : "TAIValidateRequest",
"handler" : "acme.TestSecurityContextHandler.class"
}]
@include "security/rule.config"{
"conditions":"/request/path =~ /secure(/.*)? ",
"authType" : "TAI",
"users" : ["user1"],
"groups" : ["CUSTOMERS"],
"roles" : ["ADMIN"]
}
# override the default registry type from file to ldap
/config/security/userservice/registryType="ldap"
/config/security/userservice/ldap += {
"jndiProviderUrl":"ldap://localhost:10390/",
"jndiSecurityPrincipal":"uid=admin,ou=system",
"jndiSecurityCredentials":"secret",
"jndiInitialContextFactory":"com.sun.jndi.ldap.LdapCtxFactory",
"ldapSearchScope":2,
"ldapSearchTimeLimit":30000,
"ldapUserIdRdnPattern":"uid={0}",
"ldapUserIdBaseDn":"ou=people,o=hq,dc=yourco,dc=com",
"ldapGroupAttributeType":"cn",
"ldapGroupBaseDn":"o=hq,dc=yourco,dc=com",
"ldapGroupSearchFilterPattern":"(&(uniqueMember={0}))"
}
An implementation class name of SecurityContextHandler must be specified using the /config/handlers stanza
so that it can be invoked when the TAIValidateRequest event runs.
The /config/security/rule.config stanza is configuration for secured URIs and authorized users, groups and roles.
See the Security considerations section for more information about this stanza.
The /config/security/userservice stanza is part of the user registry configuration used by authorization.
See the LDAP user service section for more information about this stanza.