custom idenetity asserter Archive

Custom Identity Asserter for Weblogic Server

Identity Asserters are used in token based authentication mechanism. It’s very useful when we have to implement Single Sign on between WLS and some other Server. A Single Identity Asserter can support multiple token types, but only one is active at a time. We can develop an Authentication provider along with the Custom Identity Asserter if the users exists outside WLS. If we want to do perimeter authentication with users within WLS, we don’t have to develop an authenticator along with it.

The way it works is pretty straight forward. Whenever a request is made for a resource which is secure, and requires token based authentication, WLS checks the request header for the active token type. If the token is present, then the container passes it on the Identity Asserter’s assertIdentity method.

In the method we have to write the logic to parse the token and pass the token (username mostly) to the login module. The token can be passed in base64 encoded format or plain, depending on the type of token accepted by the identity asserter.

The steps to create it are the same as other providers.

First we need to create an MDF (Mbean definition file)

SimpleSampleServletAuthenticationFilter.xml

<?xml version=”1.0? ?>
<!DOCTYPE MBeanType SYSTEM “commo.dtd”>

<MBeanType
Name = “SimpleSampleIdentityAsserter”
DisplayName = “SimpleSampleIdentityAsserter”
Package = “examples.security.providers.identityassertion.simple”
Extends = “weblogic.management.security.authentication.IdentityAsserter”
PersistPolicy = “OnUpdate”
>

<MBeanAttribute
Name = “ProviderClassName”
Type = “java.lang.String”
Writeable = “false”
Preprocessor = “weblogic.management.configuration.LegalHelper.checkClassName(value)”
Default = “&quot;examples.security.providers.saf.simple.SimpleSampleServletAuthenticationFilter&quot;”
/>

<MBeanAttribute
Name = “ProviderClassName”
Type = “java.lang.String”
Writeable = “false”
Preprocessor = “weblogic.management.configuration.LegalHelper.checkClassName(value)”
Default = “&quot;examples.security.providers.identityassertion.simple.SimpleSampleIdentityAsserterProviderImpl&quot;”
/>
<MBeanAttribute
Name = “Description”
Type = “java.lang.String”
Writeable = “false”
Default = “&quot;WebLogic Simple Sample Identity Asserter Provider&quot;”
/>

<mbeanattribute
Name = “SupportedTypes”
Type = “java.lang.String[]“
Writeable = “false”
Default = “new String[] { &quot;MyToken&quot; }”
/>

<mbeanattribute
Name = “ActiveTypes”
Type = “java.lang.String[]“
Default = “new String[] { &quot; MyToken &quot; }”
/>

<MBeanAttribute
Name = “Version”
Type = “java.lang.String”
Writeable = “false”
Default = “&quot;1.0&quot;”
/>

</MBeanType>

Implement the IdentityAsserterV2 & AuthenticationProviderV2 SSPI.

SimpleSampleIdentityAsserterProviderImpl.java

/**
*
* @author faisalk
*/

package examples.security.providers.identityassertion.simple;

import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.AppConfigurationEntry;
import weblogic.management.security.ProviderMBean;
import weblogic.security.service.ContextHandler;
import weblogic.security.spi.AuthenticationProviderV2;
import weblogic.security.spi.IdentityAsserterV2;
import weblogic.security.spi.IdentityAssertionException;
import weblogic.security.spi.PrincipalValidator;
import weblogic.security.spi.SecurityServices;
import javax.servlet.http.HttpServletRequest;

public final class SimpleSampleIdentityAsserterProviderImpl implements AuthenticationProviderV2, IdentityAsserterV2
{
final static private String TOKEN_TYPE = “MyToken”;
final static private String TOKEN_PREFIX = “username=”;
private String description;

public void initialize(ProviderMBean mbean, SecurityServices services)
{
System.out.println(“SimpleSampleIdentityAsserterProviderImpl.initialize”);
SimpleSampleIdentityAsserterMBean myMBean = (SimpleSampleIdentityAsserterMBean)mbean;
description= myMBean.getDescription() + “\n” + myMBean.getVersion();
}

public String getDescription()
{
return description;
}

public void shutdown()
{
System.out.println(“SimpleSampleIdentityAsserterProviderImpl.shutdown”);
}

public IdentityAsserterV2 getIdentityAsserter()
{
return this;
}

public CallbackHandler assertIdentity(String type, Object token, ContextHandler context) throws IdentityAssertionException
{
System.out.println(“SimpleSampleIdentityAsserterProviderImpl.assertIdentity”);
System.out.println(“\tType\t\t= ” + type);
System.out.println(“\tToken\t\t= ” + token);

Object requestValue = context.getValue(“com.bea.contextelement.servlet.HttpServletRequest”);
if ((requestValue == null) || (!(requestValue instanceof HttpServletRequest)))
{
System.out.println(“do nothing”);
}
else{
HttpServletRequest request = (HttpServletRequest) requestValue;
java.util.Enumeration names = request.getHeaderNames();
while(names.hasMoreElements()){
String name = (String) names.nextElement();
System.out.println(name + “:” + request.getHeader(name));
}
}

// check the token type
if (!(TOKEN_TYPE.equals(type))) {
String error =” received unknown token type \”” + type + “\”.” +” Expected ” + TOKEN_TYPE;
System.out.println(“\tError: ” + error);
throw new IdentityAssertionException(error);
}

// make sure the token is an array of bytes
if (!(token instanceof byte[])) {
String error =”unknown token class \”” + token.getClass() + “\”.” +” Expected a byte[].”;
System.out.println(“\tError: ” + error);
throw new IdentityAssertionException(error);
}

// convert the array of bytes to a string
byte[] tokenBytes = (byte[])token;
if (tokenBytes == null || tokenBytes.length < 1) {String error =”received empty token byte array”;System.out.println(“\tError: ” + error);throw new IdentityAssertionException(error);}String tokenStr = new String(tokenBytes);// make sure the string contains “username=someusernameif (!(tokenStr.startsWith(TOKEN_PREFIX))) {String error =”received unknown token string \”” + type + “\”.” +” Expected ” + TOKEN_PREFIX + “username”;System.out.println(“\tError: ” + error);throw new IdentityAssertionException(error);}// extract the username from the tokenString userName = tokenStr.substring(TOKEN_PREFIX.length());System.out.println(“\tuserName\t= ” + userName);// store it in a callback handler that authenticators can use// to retrieve the username.return new SimpleSampleCallbackHandlerImpl(userName);}public AppConfigurationEntry getLoginModuleConfiguration(){return null;}public AppConfigurationEntry getAssertionModuleConfiguration(){return null;}public PrincipalValidator getPrincipalValidator(){return null;}}Copy the Provider Class and the MDF in a folder.Keep the following build script in the same folderbuild.xml

<project name=”Expenselink Build” default=”all” basedir=”.”>
<property name=”fileDir” value=”test” />

<target name=”all” depends=”build”/>

<target name=”build” depends=”clean,build.mdf,build.mjf”/>

<target name=”clean”>
<delete dir=”${fileDir}” failonerror=”false”/>
<delete file=”SimpleSampleIdentityAsserter.jar” failonerror=”false”/>
<echo message=”Clean finish” />
</target>

<!– helper to build an MDF (mbean definition file) –>
<target name=”build.mdf”>
<java dir=”${basedir}” fork=”false” classname=”weblogic.management.commo.WebLogicMBeanMaker”>
<arg line=”-files ${fileDir}” />
<arg value=”-createStubs” />
<arg line=”-MDF SimpleSampleIdentityAsserter.xml” />
</java>
<echo message=”Created Supporting Classes” />
</target>

<target name=”build.mjf”>

<copy todir=”${fileDir}” flatten=”true”>
<fileset dir=”.”>
<include name=”*.java” />
</fileset>
</copy>

<java dir=”${basedir}” fork=”false” classname=”weblogic.management.commo.WebLogicMBeanMaker”>
<arg line=”-MJF SimpleSampleIdentityAsserter.jar” />
<arg line=”-files ${fileDir}” />
</java>
<echo message=”Created Mbean Jar” />
</target>

</project>

Copy commo.dtd present in server lib to this directory.
Execute setWLSEnv.cmd and cd to this directory.
Type ant in the command prompt
An Identity Asserter jar file would be created in the same directory.

Place this jar file in WL_HOME\server\lib\mbeantypes
Restart the Server.
Go to Security Realm Providers, create a new Authentication Provider
Home > Summary of Security Realms > myrealm > Providers > Authentication > new Simple Sample Identity Asserter

On restart Identity Asserter will get invoked whenever the active token is present in the header.

References:-
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/dvspisec/ia.html