Weblogic Server - Developing Custom User Principal Object

Introduction to Weblogic Principal Validation Provider:

The default security realm for WebLogic Server includes a WebLogic Principal Validation provider. A Principal Validation provider signs and verifies the authenticity of a specific type of principal. The WebLogic Principal Validation(which comes with weblogic server you can also write custom Principal Validation Provider) provider signs and verifies WebLogic Server principals. In other words, it signs and verifies principals that represent WebLogic Server users or WebLogic Server groups.

Authentication providers rely on Principal Validation providers to sign and verify the authenticity of principals (users and groups) contained within a subject.Verification of the subject's principals takes place during the WebLogic Server's demarshalling of RMI client requests for each invocation. The authenticity of the subject's principals is also verified when making authorization decisions.

A Principal Validation provider is a special type of security provider that primarily acts as a "helper" to an Authentication provider. The main function of a Principal Validation provider is to prevent malicious individuals from tampering with the principals stored in a subject. The AuthenticationProvider SSPI includes a method called getPrincipalValidator. In this method, you specify the Principal Validation provider's runtime class to be used with the Authentication provider. The Principal Validation provider's runtime class can be the one BEA provides (called the WebLogic Principal Validation provider) or one you develop (called a custom Principal Validation provider).

The Principal Validation provider that is associated with the configured Authentication provider will sign and verify all the principals stored in the subject that are of the type the Principal Validation provider is designed to support.

Now we are going to discuss Developing Custom User Principal Object:

If you have user or group principals with extra data members (that is, in addition to a name), and you want to use the WebLogic Principal Validation provider:

1) Write your own UserImpl and GroupImpl classes.

2) Extend the weblogic.security.principal.WLSAbstractPrincipal class.

3) Implement the weblogic.security.spi.WLSUser and weblogic.security.spi.WLSGroup interfaces.

4) Implement the equals() method to include your extra data members. Your implementation should call the super.equals() method when complete so the WLSAbstractPrincipal can validate the remaining data.

5) By default, only the user or group name will be validated. If you want to validate your extra data members as well, then implement the getSignedData() method.

In the below code I have user with extra parameters country and city.

 package com.custom.wls.security.providers.authentication;  
 import weblogic.security.principal.WLSAbstractPrincipal;  
 import weblogic.security.spi.WLSUser;  
 /**   
  * @author murali   
  *   
 */   
 public final class CustomUserImpl extends WLSAbstractPrincipal implements WLSUser{  
  private static final long serialVersionUID = 1L;  
  String city = "NewYork";  
  String country = "US";  
  public CustomUserImpl(String paramString) {  
   setName(paramString);  
  }  
  public String getCity() {  
   return this.city;  
  }  
  public void setCity(String city) {  
   this.city = city;  
  }  
  public String getCountry() {  
   return this.country;  
  }  
  public void setCountry(String country) {  
   this.country = country;  
  }  
  public boolean equals(CustomUserImpl customUserImpl) {  
   boolean bool1 = this.city.equals(customUserImpl.city);  
   boolean bool2 = this.country.equals(customUserImpl.country);  
   boolean bool3 = super.equals(customUserImpl);  
   int i = (bool1) && (bool2) && (bool3) ? 1 : 0;  
   return i;  
  }  
 }  

Now compile this class and create a jar which consists of only this class file. Lets say the name of the jar is customsecurity.jar which consists of com.custom.wls.security.providers.authentication.CustomUserImpl.class

This Jar file should be loaded in the SystemClassloader.

In commEnv.sh search for "set WEBLOGIC_CLASSPATH", in the classpath include customsecurity.jar.

For example as shown below.

set WEBLOGIC_CLASSPATH=%JAVA_HOME%\lib\tools.jar;%WL_HOME%\server\lib\customsecurity.jar;%WL_HOME%\server\lib\weblogic_sp.jar;

Now we have to add this custom user principal object in Authentication Provider Implementation to add this to the subject.

In the URL http://docs.oracle.com/cd/E17904_01/web.1111/e13718/atn.htm#i1185262  its been mentioned the login method. Once the login is success you add WLSUserImpl to the subject

Instead of adding
principalsForSubject.add(new WLSUserImpl(userName));  

We add the below code

CustomUserImpl customUserImpl = new MyUserImpl(str);  
customUserImpl.setCity("London");  
customUserImpl.setCountry("UK");  
principalsForSubject.add(customUserImpl);  

 

 The complete login method will look as shown below.

 public boolean login() throws LoginException   
   {  
    // only called (once!) after initialize  
    System.out.println("SimpleSampleLoginModuleImpl.login");  
    // loginSucceeded    should be false  
    // principalsInSubject should be false  
    Callback[] callbacks = getCallbacks();  
    String userName = getUserName(callbacks);  
    if (userName.length() > 0) {  
      if (!database.userExists(userName)) {  
       throwFailedLoginException("Authentication Failed: User " + userName   
       + " doesn't exist.");  
      }  
     if (!isIdentityAssertion) {  
      String passwordWant = null;  
      try {  
       passwordWant = database.getUserPassword(userName);  
      } catch (NotFoundException shouldNotHappen) {}  
       String passwordHave = getPasswordHave(userName, callbacks);  
       if (passwordWant == null || !passwordWant.equals(passwordHave)) {  
         throwFailedLoginException(  
          "Authentication Failed: User " + userName + " bad password."   
         );  
       }  
      }  
      } else {   
      // anonymous login - let it through?  
      System.out.println("\tempty userName");  
      }  
      loginSucceeded = true;  
      CustomUserImpl customUserImpl = new MyUserImpl(str);  
      customUserImpl.setCity("London");  
      customUserImpl.setCountry("UK");  
      principalsForSubject.add(customUserImpl);  
      addGroupsForSubject(userName);  
      return loginSucceeded;  
   }  

Note: You should always refer to the customsecurity.jar in your Authentication Provider or in your application but never copy the jar in your application which may lead to ClassCastException.

In your application access the user principal object as shown below once you logged in:

    Subject subject = Security.getCurrentSubject();   
       Set<Principal> principals = subject.getPrincipals();  
       CustomUserImpl customUserImpl= null;  
       WLSUserImpl wlsUserImpl= null  
    for(Principal principal : principals)   
    {  
     try {  
         if (principal.getClass().toString().endsWith("CustomUserImpl")){  
           customUserImpl = (CustomUserImpl)principal;  
           System.out.println("Country:"+customUserImpl.getCountry());  
                       System.out.println("City:"+customUserImpl.getCity());  
         }  
         if (principal.getClass().toString().endsWith("WLSUserImpl"))  
         {  
          wlsUserImpl = (WLSUserImpl) principal;  
          System.out.println(wlsUserImpl.getName());  
         }  
     }   

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today