Show TOC Entering content frame

Background documentation Customized Authentication Implementation Locate the document in its SAP Library structure

In this section a customized authentication is implemented that will accept a password if it is equal to the user name after a cyclic right-shiftby one character. The comparison is not case sensitive.

The class of the example is called com.sap.security.demo.DemoLoginModule.

Implementing the LoginModule Interface

The LoginModuleinterface provides the method necessary to implement the customized authentication. In the following we describe the methods that have to be implemented.

checkPasswd(String user, char [] pwd) Method

This method verifies the password.

Note

The password parameter pwd comes in a character array in compliance with the JAAS standard.

The method is implemented as follows:

/**
 *  This function verified if the password is a cyclic
 *  right shift by one character of the lowercase user
 *  name  
 */
 
protected boolean checkPasswd (String name, char [] pwd)
 {        
   
if (name==null || pwd==null || name.length()==0 || pwd.length==0) {
        
return false;
   }
   name = name.toLowerCase();
 
 
// cut off the first character
   
String strPwd = new String (pwd, 1, pwd.length-1);
 
 
// compare if the first character of the password
 // is the last of the user name
   
if (pwd[0]!=name.charAt(name.length()-1))
       
return false;
 
   
return name.substring (0,name.length()-1).equals(strPwd);
 }

 

initialize() Method

This method is called when the service is initialized, for example when the portal is started.

 Subject         _subject    = null;
 CallbackHandler _ch         = null;

 public void initialize(Subject subj, CallbackHandler ch,
                        Map sharedState, Map options)
 {
        _subject = subj;
        _ch      = ch;
 }

Note

To save resources the portal cannot keep the login context. Therefore the settings are not available in the sharedState map for an entire logon/logoff cycle. A new sharedState map is instantiated before the methods login() or logoff() are called.

 

login() Method

This method is called, when the user chooses the Logon button on the logon screen. The login() method gets the username and password. It checks the password and returns true, when the password is correct, or an exception when the password is incorrect.

public boolean login() throws LoginException
{
     Exception        exception_on_the_way    = 
null;
     PasswordCallback pc = 
new PasswordCallback ("Password:"false);
     NameCallback     nc = 
new NameCallback ("User:");
     Callback []      mycallbacks = 
new Callback [] { nc, pc };
     
     
try {
       _ch.handle (mycallbacks);
     }
     
catch (IOException e) {
        exception_on_the_way = e;
     }
     
catch (UnsupportedCallbackException e) {
        exception_on_the_way = e;
     }
 
     String name = nc.getName();
     
char [] pwd = pc.getPassword();
 
     
if (name.length()==0)
        
throw new LoginException (MISSING_UID);
 
     
if (pwd.length==0)
        
throw new LoginException (MISSING_PASSWORD);
 
     
if (exception_on_the_way!=null) {
  
// A productive application should write an entry
  // into the trace here
         
exception_on_the_way.printStackTrace ();
         
throw new LoginException ("Could not handle callbacks");
     }
 
     
if (!checkPasswd (name, pwd)) {
         
throw new LoginException (USER_AUTH_FAILED);
     }
     
else {
         _bSucceeded = 
true;
         _auth_user  = name;
     }
 
     
return true;
}

If a LoginException exception is thrown in the method login(), like shown in the example above, the standard logon page of the portal displays the standard error messages for the standard error cases, like user or password incorrect.

To display a specific message on the logon page, a javax.security.auth.login.LoginException with a defined error constant has to be thrown. The error constants are defined as String constants in the core class com.sap.security.core.logon.imp.SecurityPolicy. Since the core class is not part of the published UME API the error codes have to be defined as follows:

 public final static String MISSING_UID      = "MISSING_UID";
 
public final static String MISSING_PASSWORD = "MISSING_PASSWORD";
 
public final static String USER_AUTH_FAILED = "USER_AUTH_FAILED";
 
public final static String USERID_NOT_FOUND = "USERID_NOT_FOUND";
 
public final static String ACCOUNT_LOCKED_ADMIN = "ACCOUNT_LOCKED_ADMIN";
 
public final static String ACCOUNT_LOCKED_LOGON = "ACCOUNT_LOCKED_LOGON";

 

commit() Method

This method is called, when the login() method returned true. It provides the identity of the authenticated user.

 public boolean commit ()
 {
    if (_bSucceeded == false) {
        
return false;
    }
    
else {
    
// add a Principal (authenticated identity) to the Subject
        
final String final_name = _auth_user;
        _subject.getPrincipals().add (
new Principal () {
             
public String getName ()
             {
                 
return final_name;
             }
        });
        
return true;
    }
 
}

The user name used to create the Principal object has to be the logon user ID of an existing portal user. The SAP Enterprise Portal will instantiate a com.sap.security.api.IUserobject with the method IUserFactory.getUserByLogonID(String logonuid).

 

Deploying the Customized Authentication

Build a Java Archive (JAR) file that contains the customized authentication implementation and other classes that the implementation needs.

For this example the class files of the com.sap.security.demo.DemoLoginModule implementation is put into the demolm.jar file. The demolm.jar file has to be copied into the folder <j2ee home>/cluster/server/additional-lib.

To register the customized authentication the configuration of the portal has to be changed. See section Configure the Portal for Customized Authentication for more details.

 

Leaving content frame