Simple Sample Custom Identity Asserter for Weblogic Server 12c

To implement a custom identity asserter for Weblogic Server we need to write a provide that implements AuthenticationProviderV2 and IdentityAsserterV2. We need to write and Mbean definition file and a callback handler.

SimpleSampleIdentityAsserterProviderImpl

 

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   = "SamplePerimeterAtnToken"; 
  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("tTypett= "  + type);
    System.out.println("tTokentt= " + 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 =
        "SimpleSampleIdentityAsserter 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 = 
        "SimpleSampleIdentityAsserter received 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 =
        "SimpleSampleIdentityAsserter 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=someusername
    if (!(tokenStr.startsWith(TOKEN_PREFIX))) {
      String error =
        "SimpleSampleIdentityAsserter received unknown token string "" + type + ""." +
        " Expected " + TOKEN_PREFIX + "username";
      System.out.println("tError: " + error);
      throw new IdentityAssertionException(error);
    }

    // extract the username from the token
    String userName = tokenStr.substring(TOKEN_PREFIX.length());
    System.out.println("tuserNamet= " + 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;
  }
}

SimpleSampleCallbackHandlerImpl

 

package examples.security.providers.identityassertion.simple;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

/*package*/ class SimpleSampleCallbackHandlerImpl implements CallbackHandler
{
  private String userName; // the name of the user from the identity assertion token

  /*package*/ SimpleSampleCallbackHandlerImpl(String user)
  {
    userName = user;
  }

  public void handle(Callback[] callbacks) throws UnsupportedCallbackException
  {
    // loop over the callbacks
    for (int i = 0; i < callbacks.length; i++) {

      Callback callback = callbacks[i];

      // we only handle NameCallbacks
      if (!(callback instanceof NameCallback)) {
        throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
      }

      // send the user name to the name callback:
      NameCallback nameCallback = (NameCallback)callback;
      nameCallback.setName(userName);
    }
  }
}

SimpleSampleIdentityAsserter.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.identityassertion.simple.SimpleSampleIdentityAsserterProviderImpl&quot;"
 />

 <MBeanAttribute
  Name          = "Description"
  Type          = "java.lang.String"
  Writeable     = "false"
  Default       = "&quot;WebLogic Simple Sample Identity Asserter Provider&quot;"
 />

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

 <MBeanAttribute  
  Name 		= "SupportedTypes"
  Type 		= "java.lang.String[]"
  Writeable 	= "false"
  Default 	= "new String[] { &quot;SamplePerimeterAtnToken&quot; }"
 />

 <MBeanAttribute  
  Name 		= "ActiveTypes"
  Type 		= "java.lang.String[]"
  Default 	= "new String[] { &quot;SamplePerimeterAtnToken&quot; }"
 />

   <MBeanAttribute  
  Name 		= "Base64DecodingRequired"
  Type 		= "boolean"
  Writeable 	= "true"
  Default 	= "false"
 />

</MBeanType>

Create a build.xml as follows.

<project name="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="SampleIdentityAsserter.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 SampleIdentityAsserter.jar" />
			<arg line="-files ${fileDir}" />
		</java>
		<echo message="Created Mbean Jar" />
	</target>

</project>

Keep all these files in the same directory. Copy setWLSEnv.cmd from WL_HOMEserverbin and commo.dtd from WL_HOMEserverlib to this diretory. The directory will then have the following files.

 

files

 

 

Run Ant

C:Replicationidentityasserter12c>ant build

Buildfile: build.xml

clean:
[delete] Deleting directory C:Replicationidentityasserter12ctest
[delete] Deleting: C:Replicationidentityasserter12cSampleIdentityAsserter.
jar
[echo] Clean finish

build.mdf:
[java] Working directory ignored when same JVM is used.
[java] Parsing the MBean definition file: SimpleSampleIdentityAsserter.xml
[echo] Created Supporting Classes

build.mjf:
[copy] Copying 2 files to C:Replicationidentityasserter12ctest
[java] Working directory ignored when same JVM is used.
[java] Creating an MJF from the contents of directory test…
[java] Compiling the files…
[java] Creating the list.
[java] Doing the compile.
[java] WLMaker-SubProcess: : EXTRACT FROM C:/bea12c/WLSERV~1.1/serverlibm
beantypeswlManagementMBean.jar
[java] WLMaker-SubProcess: : INTO wlMakerTempDir
[java] WLMaker-SubProcess: :
[java] WLMaker-SubProcess: :
[java] WLMaker-SubProcess: :
[java] WLMaker-SubProcess: : Generating the implementations for security MB
eans
[java] WLMaker-SubProcess: : Generating for examples.security.providers.ide
ntityassertion.simple.SimpleSampleIdentityAsserterMBean to C:Replicationidenti
tyasserter12ctestexamplessecurityprovidersidentityassertionsimpleSimpleSa
mpleIdentityAsserterMBeanImpl.java
[java] WLMaker-SubProcess: : no annotation found for key [i]
[java] WLMaker-SubProcess: : no annotation found for key [velocityCount]
[java] WLMaker-SubProcess: : no annotation found for key [line]
[java] WLMaker-SubProcess: : no annotation found for key [f]
[java] WLMaker-SubProcess: : no annotation found for key [m]
[java] WLMaker-SubProcess: : no annotation found for key [p]
[java] WLMaker-SubProcess: : no annotation found for key [n]
[java] WLMaker-SubProcess: : done
[java] WLMaker-SubProcess: :
[java] WLMaker-SubProcess: :
[java] WLMaker-SubProcess: :
[java] WLMaker-SubProcess: : Generating the parsing binders for security MB
eans
[java] WLMaker-SubProcess: : Generating for examples.security.providers.ide
ntityassertion.simple.SimpleSampleIdentityAsserterMBean to C:Replicationidenti
tyasserter12ctestexamplessecurityprovidersidentityassertionsimpleSimpleSa
mpleIdentityAsserterMBeanBinder.java
[java] WLMaker-SubProcess: : done
[java] WLMaker-SubProcess: :
[java] WLMaker-SubProcess: :
[java] WLMaker-SubProcess: :
[java] WLMaker-SubProcess: : Generating the bean infos for security MBeans

[java] WLMaker-SubProcess: : Generating for examples.security.providers.ide
ntityassertion.simple.SimpleSampleIdentityAsserterMBean to C:Replicationidenti
tyasserter12ctestexamplessecurityprovidersidentityassertionsimpleSimpleSa
mpleIdentityAsserterMBeanImplBeanInfo.java
[java] WLMaker-SubProcess: : no annotation found for key [import]
[java] WLMaker-SubProcess: : no annotation found for key [property]
[java] WLMaker-SubProcess: : no annotation found for key [beanConfigurable]

[java] WLMaker-SubProcess: : no annotation found for key [beanIntfExclude]
[java] WLMaker-SubProcess: : no annotation found for key [propertyMethod]
[java] WLMaker-SubProcess: : no annotation found for key [method]
[java] WLMaker-SubProcess: : Generating Bean Factory Class to testweblogic
managementsecuritySAMPLEIDENTITYASSERTERBeanInfoFactory.java
[java] WLMaker-SubProcess: : done
[java] WLMaker-SubProcess: : Stopped draining WLMaker-SubProcess:
[java] WLMaker-SubProcess: : Stopped draining WLMaker-SubProcess:
[java] WLMaker-SchemaGen-SubProcess: Generating schema for security provide
r mbeans …
[java] WLMaker-SchemaGen-SubProcess: MBEAN TYPES DIR : null
[java] WLMaker-SchemaGen-SubProcess: SET BASE LIB C:bea12cWLSERV~1.1serv
erlibschemaweblogic-domain-binding.jar
[java] WLMaker-SchemaGen-SubProcess: Stopped draining WLMaker-SchemaGen-Sub
Process
[java] WLMaker-SchemaGen-SubProcess: Stopped draining WLMaker-SchemaGen-Sub
Process
[java] Creating the list.
[java] Doing the compile.
[java] Note: C:Replicationidentityasserter12ctestexamplessecurityprov
idersidentityassertionsimpleSimpleSampleIdentityAsserterMBeanImpl.java uses o
r overrides a deprecated API.
[java] Note: Recompile with -Xlint:deprecation for details.
[java] Note: Some input files use unchecked or unsafe operations.
[java] Note: Recompile with -Xlint:unchecked for details.
[java] Creating the MJF…
[java] MJF is created.

 

An  Mbean JAR file will b created in that directory with the name SampleIdentityAsserter.jar

Place this jar file in WL_HOMEserverlibmbeantypes

 

mbeantype

 

After placing the jar file, restart the Weblogic server.

Go to Security Realm Providers, create a new Authentication Provider
Home > Summary of Security Realms > myrealm > Providers > Authentication > new Simple Sample Identity Asserter

 

Simple Sample Identity Asserter

 

Once the identity asserter is created reorder the providers to make it first in the list. One more restart is required. On restart the custom identity asserter will be initialized. When any secure resource is accessed on the server and the token is present in the header the Custom Identity Asserter is invoked. Note, this identity asserter does not expect Base64 encoded token.

You will see the following loggging when the identity asserter is invoked.

SimpleSampleIdentityAsserterProviderImpl.assertIdentity
Type = SamplePerimeterAtnToken
Token = [B@c4221d
SamplePerimeterAtnToken:username=SamplePerimeterAtnUsers
User-Agent:Java/1.6.0_37
Host:localhost:7001
Accept:text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection:keep-alive
userName = SamplePerimeterAtnUsers
Header Name SamplePerimeterAtnToken Content username=SamplePerimeterAtnUsers
Header Name User-Agent Content Java/1.6.0_37
Header Name Host Content localhost:7001
Header Name Accept Content text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Header Name Connection Content keep-alive

 

 

 

 

9 comments

  1. I am trying this on WEblogic Version : 12.1.2.00, but getting an error on the weblogic restart

    [Security:097534]Failed to obtain an instance of class examples.security.providers.identityassertion.simple.SimpleSampleIdentityAsserterProviderImpl.

    1. I had the same problem. I had renamed things and moved things around, and this was causing it. All files must be in the root of your project, and the Impl.java class may conflict naming-wise with a generated class that is part of the MBean building process. If that’s the case, your logs will give a NoSuchMethodException on the constructor of the Impl class. You need to rename the Impl class (and adapt the mbean xml file accordingly), and the problem goes away.

  2. I am using this and getting redirected to the weblogic login screen which I am unable to bypass. Note the users I am trying to validate using this Identity Asserter have are not created in weblogic. I have created a Active directory Authenticator to get them.

    Is there any code that I have to add here to guide the callback handler to search the user in the Active directory Authenticator?

  3. I am getting below error
    [java] SimpleSampleIdentityAsserterMBean myMBean = (SimpleSampleIdentit
    yAsserterMBean)mbean;
    [java] ^
    [java] symbol: class SimpleSampleIdentityAsserterMBean
    [java] location: class SimpleSampleIdentityAsserterProviderImpl
    [java] D:\FNDMS\MJF\test\SimpleSampleIdentityAsserterProviderImpl.java:19:
    error: cannot find symbol
    [java] SimpleSampleIdentityAsserterMBean myMBean = (SimpleSampleIdentit
    yAsserterMBean)mbean;
    [java] ^
    [java] symbol: class SimpleSampleIdentityAsserterMBean
    [java] location: class SimpleSampleIdentityAsserterProviderImpl
    [java] 2 errors
    [java] Exec failed .. exiting
    [java] org.apache.tools.ant.ExitException: Permission (“java.lang.RuntimePe
    rmission” “exitVM”) was not granted.
    [java] at org.apache.tools.ant.types.Permissions$MySM.checkExit(Permiss
    ions.java:193)
    [java] at java.lang.Runtime.exit(Runtime.java:107)
    [java] at java.lang.System.exit(System.java:971)
    [java] at weblogic.utils.compiler.CompilerInvoker.compileMaybeExit(Comp
    ilerInvoker.java:497)
    [java] at weblogic.utils.compiler.CompilerInvoker.compile(CompilerInvok
    er.java:332)
    [java] at weblogic.management.commo.WebLogicMBeanMaker.compile(WebLogic
    MBeanMaker.java:1057)
    [java] at weblogic.management.commo.WebLogicMBeanMaker.compile(WebLogic
    MBeanMaker.java:1018)
    [java] at weblogic.management.commo.WebLogicMBeanMaker.main(WebLogicMBe
    anMaker.java:735)
    [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcces
    sorImpl.java:62)
    [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMet
    hodAccessorImpl.java:43)
    [java] at java.lang.reflect.Method.invoke(Method.java:497)
    [java] at org.apache.tools.ant.taskdefs.ExecuteJava.run(ExecuteJava.jav
    a:217)
    [java] at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava
    .java:152)
    [java] at org.apache.tools.ant.taskdefs.Java.run(Java.java:771)
    [java] at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:221)

    [java] at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:135)

    [java] at org.apache.tools.ant.taskdefs.Java.execute(Java.java:108)
    [java] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.ja
    va:292)
    [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcces
    sorImpl.java:62)
    [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMet
    hodAccessorImpl.java:43)
    [java] at java.lang.reflect.Method.invoke(Method.java:497)
    [java] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchU
    tils.java:106)
    [java] at org.apache.tools.ant.Task.perform(Task.java:348)
    [java] at org.apache.tools.ant.Target.execute(Target.java:435)
    [java] at org.apache.tools.ant.Target.performTasks(Target.java:456)
    [java] at org.apache.tools.ant.Project.executeSortedTargets(Project.jav
    a:1393)
    [java] at org.apache.tools.ant.Project.executeTarget(Project.java:1364)

    [java] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(De
    faultExecutor.java:41)
    [java] at org.apache.tools.ant.Project.executeTargets(Project.java:1248
    )
    [java] at org.apache.tools.ant.Main.runBuild(Main.java:851)
    [java] at org.apache.tools.ant.Main.startAnt(Main.java:235)
    [java] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    [java] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
    [java] WLMaker-SubProcess: : EXTRACT FROM D:/Products/Oracle/Middleware/wls
    erver/server\lib\mbeantypes\wlManagementMBean.jar
    [java] WLMaker-SubProcess: : INTO wlMakerTempDir
    [java] WLMaker-SubProcess: :
    [java] WLMaker-SubProcess: :
    [java] WLMaker-SubProcess: :
    [java] WLMaker-SubProcess: : Generating the implementations for security MB
    eans
    [java] WLMaker-SubProcess: : Generating for examples.security.providers.ide
    ntityassertion.simple.DMSIdentityAsserterMBean to D:\FNDMS\MJF\test\examples\sec
    urity\providers\identityassertion\simple\DMSIdentityAsserterMBeanImpl.java
    [java] WLMaker-SubProcess: : no annotation found for key [i]
    [java] WLMaker-SubProcess: : no annotation found for key [velocityCount]
    [java] WLMaker-SubProcess: : no annotation found for key [line]
    [java] WLMaker-SubProcess: : no annotation found for key [f]
    [java] WLMaker-SubProcess: : no annotation found for key [m]
    [java] WLMaker-SubProcess: : no annotation found for key [p]
    [java] WLMaker-SubProcess: : no annotation found for key [n]
    [java] WLMaker-SubProcess: : done
    [java] WLMaker-SubProcess: :
    [java] WLMaker-SubProcess: :
    [java] WLMaker-SubProcess: :
    [java] WLMaker-SubProcess: : Generating the bean infos for security MBeans

    [java] WLMaker-SubProcess: : Generating for examples.security.providers.ide
    ntityassertion.simple.DMSIdentityAsserterMBean to D:\FNDMS\MJF\test\examples\sec
    urity\providers\identityassertion\simple\DMSIdentityAsserterMBeanImplBeanInfo.ja
    va
    [java] WLMaker-SubProcess: : no annotation found for key [import]
    [java] WLMaker-SubProcess: : no annotation found for key [property]
    [java] WLMaker-SubProcess: : no annotation found for key [beanConfigurable]

    [java] WLMaker-SubProcess: : no annotation found for key [beanIntfExclude]
    [java] WLMaker-SubProcess: : no annotation found for key [propertyMethod]
    [java] WLMaker-SubProcess: : no annotation found for key [method]
    [java] WLMaker-SubProcess: : Generating Bean Factory Class to test\weblogic
    \management\security\DMSIDENTITYASSERTERBeanInfoFactory.java

  4. Hi where can I find this
    SimpleSampleIdentityAsserterMBean

    got compilation error

    Thanks

    1. You need to check your classpath… you can do a setWLSEnv.sh to set the classpath..

Comments are closed.