Simple Sample Custom Database Authenticator for Oracle Weblogic Server 11g

To create a custom database authenticator for oracle weblogic server, you will have to implement the AuthenticationProviderV2, create an MBean definition file and create a class that implements LoginModule.
I am providing the sample code below and also the steps to create and install it on your server.

DBAuthenticationProviderImpl

 

package com.wonders.security.dbauthentication;

import java.util.HashMap;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import weblogic.management.security.ProviderMBean;
import weblogic.security.provider.PrincipalValidatorImpl;
import weblogic.security.spi.AuthenticationProviderV2;
import weblogic.security.spi.IdentityAsserterV2;
import weblogic.security.spi.PrincipalValidator;
import weblogic.security.spi.SecurityServices;
import weblogic.security.principal.WLSGroupImpl;
import weblogic.security.principal.WLSUserImpl;

public class DBAuthenticationProviderImpl implements AuthenticationProviderV2 {

   private String a_sDescription;
   private DBAuthenticatorDatabase a_oDatabase;
   private LoginModuleControlFlag a_oControlFlag;
   private String a_sDataSourceJNDIName;
   private String a_sSystemUserName;

   public void initialize(ProviderMBean mbean, SecurityServices services)
   {
      System.out.println("DBAuthenticationProviderImpl.initialize");
	  DBAuthenticatorMBean oMyMBean = (DBAuthenticatorMBean)mbean;
	  a_sDescription = oMyMBean.getDescription() + "n" + oMyMBean.getVersion();
	  a_sDataSourceJNDIName = oMyMBean.getDataSourceJNDIName();
	  a_sSystemUserName = oMyMBean.getSystemUserName();

	  a_oDatabase = new DBAuthenticatorDatabase(a_sDataSourceJNDIName, a_sSystemUserName);

	  String flag = oMyMBean.getControlFlag();
	  if (flag.equalsIgnoreCase("REQUIRED")) {
		    a_oControlFlag = LoginModuleControlFlag.REQUIRED;
		  } else if (flag.equalsIgnoreCase("OPTIONAL")) {
		    a_oControlFlag = LoginModuleControlFlag.OPTIONAL;
		  } else if (flag.equalsIgnoreCase("REQUISITE")) {
		    a_oControlFlag = LoginModuleControlFlag.REQUISITE;
		  } else if (flag.equalsIgnoreCase("SUFFICIENT")) {
		    a_oControlFlag = LoginModuleControlFlag.SUFFICIENT;
		  } else {
		    throw new IllegalArgumentException("invalid flag value" + flag);
	      }
	   }

	   public String getDescription()
	   {
	      return a_sDescription;
	   }

	   public void shutdown()
	   {
	      System.out.println("DBAuthenticatorDatabase.shutdown");
	   }

	   private AppConfigurationEntry getConfiguration(HashMap options)
	   {
	      options.put("database", a_oDatabase);
		  return new 
		    AppConfigurationEntry(
		      "com.wonders.security.dbauthentication.DBLoginModuleImpl",
		          a_oControlFlag,
		          options
		        );
	   }

	   public AppConfigurationEntry getLoginModuleConfiguration()
	   {
	      HashMap oOptions = new HashMap();
	      oOptions.put("DataSourceJNDIName",a_sDataSourceJNDIName);
	      oOptions.put("SystemUserName",a_sSystemUserName);
	      return getConfiguration(oOptions);
	   }

	   public AppConfigurationEntry getAssertionModuleConfiguration()
	   {
	      HashMap options = new HashMap();
	      options.put("IdentityAssertion","true");
	      return getConfiguration(options);
	   }

	   public PrincipalValidator getPrincipalValidator() 
	   {
	      return new PrincipalValidatorImpl();
	   }

	   public IdentityAsserterV2 getIdentityAsserter()
	   {
	      return null;
	   }

}

DBLoginModuleImpl

 

package com.wonders.security.dbauthentication;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.spi.LoginModule;
import weblogic.management.utils.NotFoundException;
import weblogic.security.spi.WLSGroup;
import weblogic.security.spi.WLSUser;
import weblogic.security.principal.WLSGroupImpl;
import weblogic.security.principal.WLSUserImpl;

public class DBLoginModuleImpl implements LoginModule {

	   private Subject a_oSubject;
	   private CallbackHandler a_oCallbackHandler;
	   private DBAuthenticatorDatabase a_oDatabase;

	   // Determine whether this is a login or assert identity 
	   private boolean a_bIsIdentityAssertion;

	   // Authentication status
	   private boolean a_bLoginSucceeded;
	   private boolean a_bPrincipalsInSubject;
	   private Vector a_collPrincipalsForSubject = new Vector();

	   public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
	   {
	      // only called (once!) after the constructor and before login

	      System.out.println("DBLoginModuleImpl.initialize");
	      this.a_oSubject = subject;
	      this.a_oCallbackHandler = callbackHandler;

	      // Check for Identity Assertion option

	      a_bIsIdentityAssertion =
	         "true".equalsIgnoreCase((String)options.get("IdentityAssertion"));

	      a_oDatabase = (DBAuthenticatorDatabase)options.get("database");
	   }

	     public boolean login() throws LoginException 
	   {
	      // only called (once!) after initialize

	      System.out.println("DBLoginModuleImpl.login");

	      // loginSucceeded       should be false
	      // principalsInSubject  should be false

	      Callback[] callbacks = getCallbacks();

	      String sUserName = getUserName(callbacks);

	      if (sUserName.length() > 0) {
				 if (!a_oDatabase.userExists_modified(sUserName)) 
				 {
				    throwFailedLoginException("Authentication Failed: User " + sUserName 
				    		+ " doesn't exist.");
				 }
				if (!a_bIsIdentityAssertion) 
				{
				     String passwordWant = null;
				     try 
				     {
				    	 String sPasswordHave = getPasswordHave( sUserName, callbacks );
				    	 if ( !a_oDatabase.authenticate_modified( sUserName, sPasswordHave, false ) ) {
				              throwFailedLoginException(
				                    "Authentication Failed: User " + sUserName + " bad password.  ");
				    	 }
				     }
				     catch (NotFoundException shouldNotHappen) 
				     {
				    	 System.out.println(shouldNotHappen.getCause());
				    	 System.out.println(shouldNotHappen.getStackTrace());

				     }
				}
	      	}	

	         a_bLoginSucceeded = true;

	         a_collPrincipalsForSubject.add(new WLSUserImpl(sUserName));
	         addGroupsForSubject(sUserName);

	         return a_bLoginSucceeded;
	   }

	   public boolean commit() throws LoginException
	   {
	      // only called (once!) after login

	      // loginSucceeded      should be true or false
	      // principalsInSubject should be false
	      // user      should be null if !loginSucceeded, null or not-null otherwise
	      // group     should be null if user == null, null or not-null otherwise

	      System.out.println("DBLoginModuleImpl.commit");

		 if (a_bLoginSucceeded) {
	         a_oSubject.getPrincipals().addAll(a_collPrincipalsForSubject);
	         a_bPrincipalsInSubject = true;
	         return true;
	      } else {
	         return false;
	      }
	   }

	   public boolean abort() throws LoginException 
	   {
	      // The abort method is called to abort the authentication process. This is
	      // phase 2 of authentication when phase 1 fails. It is called if the
	      // LoginContext's overall authentication failed.

	      // loginSucceeded      should be true or false
	      // user      should be null if !loginSucceeded, otherwise null or not-null
	      // group     should be null if user == null, otherwise null or not-null
	      // principalsInSubject      should be false if user is null, otherwise true 
	      //                          or false

	      System.out.println("DBLoginModuleImpl.abort"+a_bPrincipalsInSubject);

	      if (a_bPrincipalsInSubject) {
	         a_oSubject.getPrincipals().removeAll(a_collPrincipalsForSubject);
	         a_bPrincipalsInSubject = false;
	      }

	      return true;
	   }

	   public boolean logout() throws LoginException
	   {
	      // should never be called
	      System.out.println("DBLoginModuleImpl.logout");
	      return true;
	   }

	   private void throwLoginException(String msg) throws LoginException
	   {
	      System.out.println("Throwing LoginException(" + msg + ")");
	      throw new LoginException(msg);
	   }

	   private void throwFailedLoginException(String msg) throws FailedLoginException
	   {
	      System.out.println("Throwing FailedLoginException(" + msg + ")");
	      throw new FailedLoginException(msg);
	   }

	   private Callback[] getCallbacks() throws LoginException
	   {
	      if (a_oCallbackHandler == null) {
	         throwLoginException("No CallbackHandler Specified");
	      }

	      if (a_oDatabase == null) {
	         throwLoginException("database not specified");
	      }

	      Callback[] callbacks;

		  //modified by faisal
		  a_bIsIdentityAssertion=false;

	      if (a_bIsIdentityAssertion) {
	         callbacks = new Callback[1];
	      } else {
	         callbacks = new Callback[2];
	         callbacks[1] = new PasswordCallback("password: ",false);
	      }
	      callbacks[0] = new NameCallback("username: ");

	      try {
	          a_oCallbackHandler.handle(callbacks);
	      } catch (IOException e) {
	         throw new LoginException(e.toString());
	      } catch (UnsupportedCallbackException e) {
	         throwLoginException(e.toString() + " " + e.getCallback().toString());
	      }

	      return callbacks;
	   }

	   private String getUserName(Callback[] callbacks) throws LoginException
	   {
	      String userName = ((NameCallback)callbacks[0]).getName();
	      if (userName == null) {
	         throwLoginException("Username not supplied.");
	      }
	      System.out.println("tuserNamet= " + userName);
	      return userName;
	   }

	   private void addGroupsForSubject(String userName)
	   {
	      for (Enumeration e = a_oDatabase.getUserGroups_modified(userName); e.hasMoreElements();) 
	      {
	            String groupName = (String)e.nextElement();
	            System.out.println("tgroupNamet= " + groupName);
	            a_collPrincipalsForSubject.add(new WLSGroupImpl(groupName));
	      }
	   }

	   private String getPasswordHave(String userName, Callback[] callbacks) throws LoginException
	   {
	      PasswordCallback passwordCallback = (PasswordCallback)callbacks[1];
	      char[] password = passwordCallback.getPassword();
	      passwordCallback.clearPassword();
	      if (password == null || password.length < 1) {
	         throwLoginException("Authentication Failed: User " + userName + ". Password not supplied");
	      }
	      String passwd = new String(password);
	      System.out.println("tpasswordHavet= " + passwd);
	      return passwd;
	   }

}

DBAuthenticatorDatabase

 

package com.wonders.security.dbauthentication;

import java.sql.*;
import java.util.Enumeration;
import java.util.Vector;
import java.util.*;
import javax.naming.*;
import javax.sql.DataSource;
import weblogic.logging.NonCatalogLogger;
import weblogic.management.utils.NotFoundException;
import java.security.MessageDigest;

import com.wonders.security.*;

public final class DBAuthenticatorDatabase
{

   String a_sDataSourceName;
   String a_sSystemUserName;

   protected static DataSource a_oDataSource = null;
   private static NonCatalogLogger a_oLogger = new NonCatalogLogger( "Security.Authentication" );

   //Constructor
   public DBAuthenticatorDatabase(String p_sDataSourceName, String p_sSystemUserName )
   {
	   	a_oLogger.debug( "DBAuthenticatorDatabase.constructor()");
		this.a_sDataSourceName = p_sDataSourceName;
		this.a_sSystemUserName  = p_sSystemUserName;
   }

   public void getDataSource()  throws Exception
   {
	a_oLogger.debug("Dataset name is = " + a_sDataSourceName);

         // If we don't already have a reference to the data source,
         if ( a_oDataSource == null )
           {try
            {
               // Get the initial context from the server and use it
               // to retrieve the data source
		   Context oCtx = new InitialContext();
               a_oDataSource = ( javax.sql.DataSource ) oCtx.lookup( a_sDataSourceName );
            } catch ( NamingException e ) {
               a_oLogger.error( "Failed to get initial context or DataSource: " + e, e );
               throw e;
            }
         }
   }

   // Return a JDBC connection from the pool
   protected Connection getConnection() throws Exception
   {
          java.sql.Connection oNewConn = null;
          try
          {
              if (a_oDataSource == null)
              {
                  getDataSource();
              }

              oNewConn = a_oDataSource.getConnection();
          }

          catch ( Exception e )
          {
              a_oLogger.error( "Failed to get connection: " + e, e );
              throw new Exception();
          }
          return oNewConn;
   }

   //Return an existing connection to the DB pool
   protected void returnConnection( Connection p_oCon )
   {
         try {
            if ( p_oCon != null ) {
               p_oCon.close();
               p_oCon = null;
            }
         } catch ( SQLException e ) {
            a_oLogger.error( "Error while returning connection to the pool: " + e, e );
         }
   }

   public synchronized boolean authenticate_modified( String p_sUser, String p_sPassword, boolean p_bEncrypted ) throws NotFoundException
	{

       try {
       // Get a database connection from the connection pool
       Connection oCon = getConnection();
       PreparedStatement oPs = oCon.prepareStatement("SELECT U_PASSWORD FROM USERS WHERE U_NAME=?");
       oPs.setString(1, p_sUser);
       ResultSet oRs = oPs.executeQuery();
       boolean pExists = oRs.next();

       String password="";
       if(pExists)
       password = oRs.getString("U_PASSWORD");

       System.out.println("password=="+password+"p_sPassword=="+p_sPassword);
       if(password.equals(p_sPassword))
	   return true;

	     }catch ( SQLException e ) {
	   	   e.printStackTrace();
       }
       catch ( Exception ex ) {
	   	   	   ex.printStackTrace();
       }

	   return false;

    }

  public synchronized Enumeration getUserGroups_modified( String p_sUser ){

	   List colRoleList = new ArrayList();

	   System.out.println( "DBAuthenticatorDatabase.getUserGroups_modified() for: " + p_sUser);

		try {
    	  	// Get a database connection from the connection pool
    	  	Connection oCon = getConnection();

			PreparedStatement oPs = oCon.prepareStatement("SELECT G_NAME FROM GROUPMEMBERS WHERE G_MEMBER=?");
			oPs.setString(1, p_sUser);
			System.out.println( "DBAuthenticatorDatabase.getUserGroups_modified():executing query ");
			ResultSet oRs = oPs.executeQuery();
			System.out.println( "DBAuthenticatorDatabase.getUserGroups_modified(): query executed");

			while (oRs.next())
				colRoleList.add(oRs.getString(1));

			 returnConnection( oCon );
		 }
		  catch ( SQLException e ) {
			 a_oLogger.error( "Error checking for user existence: " + e, e );

		  } catch ( Exception ex ) {
			 a_oLogger.error( "Error checking for user existance: " + ex, ex );

		  }

		  return Collections.enumeration(colRoleList);

   }

    public synchronized boolean userExists_modified( String p_sUser )
   {

      a_oLogger.debug( "DBAuthenticatorDatabase.userExists_modified() for: " + p_sUser);

	  System.out.println( "DBAuthenticatorDatabase.userExists_modified() for: " + p_sUser);

      Connection oCon = null;
      boolean bExists = false;

	//If we are trying to log in as system, then stop  further attempts, which will require JNDI access in this facility
	//Authentication instead will pass to the default authenticator, where system user will be defined

	/* if (p_sUser.equals(a_sSystemUserName))
		return false; */

      try {

         // Get a database connection from the connection pool
         oCon = getConnection();

         // Prepare the neccessary statements in order to check if the user exists
      PreparedStatement oUsersStmt = oCon.prepareStatement("Select U_NAME,U_PASSWORD From USERS where U_NAME=?");

      // Query for a user by the specified name
      oUsersStmt.setString( 1, p_sUser );

	  System.out.println("executing query!");
      ResultSet oRS = oUsersStmt.executeQuery();
      System.out.println(" query executed");
         // Store the result of the record set (whether we found users or not)

      bExists = oRS.next();

      if(bExists = true)
	  System.out.println("usename from database "+oRS.getString("U_NAME")+" bExists"+bExists);
	  else{
		   System.out.println("User Doesnt Exist!!");
		  }

         // Clean everything up
         oRS.close();
         oUsersStmt.close();

      } catch ( SQLException e ) {
         a_oLogger.error( "Error checking for user existance: " + e, e );

      } catch ( Exception ex ) {
         a_oLogger.error( "Error checking for user existance: " + ex, ex );

      } finally {
         // Return the database connection to the pool
         returnConnection( oCon );
      }

      // Return the saved result
      a_oLogger.debug( "DBAuthenticatorDatabase.userExists_modified() for: " + p_sUser + " = " + bExists);

      return bExists;
   }

}   // class DBAuthenticatorDatabase

DBAuthenticator.xml

 

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

<MBeanType
 Name          = "DBAuthenticator"
 DisplayName   = "DBAuthenticator"
 Package       = "com.wonders.security.dbauthentication"
 Extends       = "weblogic.management.security.authentication.Authenticator"
 PersistPolicy = "OnUpdate"
>

 <MBeanAttribute
  Name          = "ProviderClassName"
  Type          = "java.lang.String"
  Writeable     = "false"
  Default       = "&quot;com.wonders.security.dbauthentication.DBAuthenticationProviderImpl&quot;"
 />

 <MBeanAttribute
  Name          = "Description"
  Type          = "java.lang.String"
  Writeable     = "false"
  Default       = "&quot; Securities Security Provider - DB Authentication &quot;"
 />

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

<MBeanAttribute
  Name          = "DataSourceJNDIName"
  Type          = "java.lang.String"
  Writeable     = "true"
  Default       = "&quot;pointbaseds&quot;"
 />

<MBeanAttribute
  Name          = "SystemUserName"
  Type          = "java.lang.String"
  Writeable     = "true"
  Default       = "&quot;system&quot;"
 />

</MBeanType>

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

</project>

Keep all the files in one location. Copy commo.dtd from WL_HOMEserverlib to this folder. Also copy WL_HOMEserverbinsetWLSEnv.cmd to this folder. The folder will look like this.

folder

Run ant to build the Mbean Jar file.

C:ReplicationsDatabaseAuthenticator>ant build
Buildfile: build.xml

clean:
[delete] Deleting directory C:ReplicationsDatabaseAuthenticatortest
[echo] Clean finish

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

build.mjf:
[copy] Copying 3 files to C:ReplicationsDatabaseAuthenticatortest
[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] Note: C:ReplicationsDatabaseAuthenticatortestDBAuthenticationPro
viderImpl.java uses or 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] WLMaker-SubProcess: : EXTRACT FROM C:/bea103/WLSERV~1.3/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 com.wonders.security.dbauthenti
cation.DBAuthenticatorMBean to C:ReplicationsDatabaseAuthenticatortestcomwo
nderssecuritydbauthenticationDBAuthenticatorMBeanImpl.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 com.wonders.security.dbauthenti
cation.DBAuthenticatorMBean to C:ReplicationsDatabaseAuthenticatortestcomwo
nderssecuritydbauthenticationDBAuthenticatorMBeanBinder.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 com.wonders.security.dbauthenti
cation.DBAuthenticatorMBean to C:ReplicationsDatabaseAuthenticatortestcomwo
nderssecuritydbauthenticationDBAuthenticatorMBeanImplBeanInfo.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
managementsecurityDBAUTHENTICATORBeanInfoFactory.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:bea103WLSERV~1.3serv
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: Some input files use or override 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.
[echo] Created Mbean Jar

build:

BUILD SUCCESSFUL
Total time: 43 seconds

 

Copy DBAuthenticator.jar to WL_HOMEserverlibmbeantypes folder.

mbeantypes

 

 

Start your server and configure your custom database authenticator.database provider

 

You will also need to create a datasource

datasource

 

The database should have the following schema for this example.

CREATE TABLE USERS (
U_NAME VARCHAR(200) NOT NULL,
U_PASSWORD VARCHAR(50) NOT NULL,
U_DESCRIPTION VARCHAR(1000));

ALTER TABLE USERS
ADD CONSTRAINT PK_USERS
PRIMARY KEY (U_NAME);

CREATE TABLE GROUPS (
G_NAME VARCHAR(200) NOT NULL,
G_DESCRIPTION VARCHAR(1000) NULL);

ALTER TABLE GROUPS
ADD CONSTRAINT PK_GROUPS
PRIMARY KEY (G_NAME);

CREATE TABLE GROUPMEMBERS (
G_NAME VARCHAR(200) NOT NULL,
G_MEMBER VARCHAR(200) NOT NULL);

ALTER TABLE GROUPMEMBERS
ADD CONSTRAINT PK_GROUPMEMS
PRIMARY KEY (
G_NAME, 
G_MEMBER
);

ALTER TABLE GROUPMEMBERS
ADD CONSTRAINT FK1_GROUPMEMBERS
FOREIGN KEY ( G_NAME )
REFERENCES GROUPS (G_NAME)
ON DELETE CASCADE

insert into USERS (U_NAME,U_PASSWORD,U_DESCRIPTION) values('system','weblogic','admin user');

insert into GROUPS (G_NAME,G_DESCRIPTION) values('Adminsitrators','Adminsitrators');

insert into GROUPMEMBERS (G_NAME,G_MEMBER) values('Administrators','system');

Once your provide is created, change the control flag of the default authenticator to SUFFICIENT.

control flag of default authenticator

 

This should be the order of the authentication providers.

order of authenticator provider

 

You can create more users in the database
insert into USERS (U_NAME,U_PASSWORD,U_DESCRIPTION) values(‘faisal’,’faisal’,’admin user’);

insert into GROUPS (G_NAME,G_DESCRIPTION) values(‘Administrators’,’Administrators’);

insert into GROUPMEMBERS (G_NAME,G_MEMBER) values(‘Administrators’,’faisal’);

Restart your server.

Try to log in to your secure application with the new user id.

You should see the following debug for a successful login.

DBLoginModuleImpl.initialize
DBLoginModuleImpl.login
userName = faisal
DBAuthenticatorDatabase.userExists_modified() for: faisal
executing query!
query executed
usename from database faisal bExiststrue
passwordHave = faisal
password==faisalp_sPassword==faisal
DBAuthenticatorDatabase.getUserGroups_modified() for: faisal
DBAuthenticatorDatabase.getUserGroups_modified():executing query
DBAuthenticatorDatabase.getUserGroups_modified(): query executed
groupName = Administrators
DBLoginModuleImpl.commit

 

 

Cheers!

Wonders Team

 

 

2 comments

  1. Thank you for sample!

    Why is there: “Also copy WL_HOME\server\bin\setWLSEnv.cmd to this folder.”, if the script should be rather called then copied?

  2. “Also copy WL_HOME\server\bin\setWLSEnv.cmd to this folder.” You do not need to copy it, but run script in shell used by ant.

Comments are closed.