Saturday, December 10, 2016

OIM 11g PS3 : Creating Access Policies using OIM Client APIs

This post is about creating Access Policies in OIM programmatically using Java APIs provided by OIM. Access policies are used in OIM for automatic provisioning of target systems to users.

To start, there is a very good Oracle Blog on OIM Java APIs. Download the code through the link provided in the blog, this will help in setting up the initial code structure and creating connection with OIM. Provide the OIM connection details as per your environment in Client.java and see if you are able to connect.

Copy Authwl.conf

Client.java
 package oim.client;  
 import java.util.Hashtable;  
 import oracle.iam.platform.OIMClient;  
 //===================================================================  
 public abstract class Client  
 //===================================================================  
 {  

   private static final String OIM_URL = "t3://:14000"; // OIM 11g deployment  
   private static final String AUTH_CONF = ""; // "/app/oracle/product/ofm/Oracle_IAM1/server/config/authwl.conf"  
   private static final String APPSERVER_TYPE = "wls";  
   private static final String WEBLOGIC_NAME = "<OIM Managed Server Name>";  
   protected static final String OIM_USERNAME = "<OIM Admin Username>";  
   protected static final String OIM_PASSWORD = "<Password>";   
   protected static final String NULL = "(null)";  
   protected static final String NL = "\n";  
   protected static final String SP = "\t";  
   protected OIMClient _oimClientAuthen = null;  
   protected OIMClient _oimClientAnon = null;  
   //----------------------------------------------------------------  
   public Client() throws Exception  
   //----------------------------------------------------------------  
   {  
    Hashtable<String, String> env = new Hashtable<String, String>();  
    System.setProperty("java.security.auth.login.config", AUTH_CONF);  
    System.setProperty("APPSERVER_TYPE", APPSERVER_TYPE);  
    System.setProperty("weblogic.Name", WEBLOGIC_NAME);  
    env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL, "weblogic.jndi.WLInitialContextFactory");  
    env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, OIM_URL);  
    _oimClientAuthen = new OIMClient(env);  
    _oimClientAuthen.login(OIM_USERNAME, OIM_PASSWORD.toCharArray());  
    _oimClientAnon = new OIMClient(env);  
    return;  
   }  
   //----------------------------------------------------------------  
   protected abstract void execute() throws Exception;  
   //----------------------------------------------------------------  

There are two types of OIM Java apis - Old Thor APIs & New Oracle APIs. I am not able to find any method under new Oracle APIs to create Access policy, so I used the old Thor API to do that. I used the new Oracle APIs to populate Access policy data, parent and child process forms, and assigning Access policies to role.

 package oim.client.policy;  
 import oim.client.Client;  
 //General Java Imports  
 import java.util.ArrayList;  
 import java.util.HashMap;  
 import java.util.List;  
 import java.util.Map;  
 //Thor APIs  
 import com.thortech.xl.vo.AccessPolicyResourceData;  
 import Thor.API.tcResultSet;  
 import Thor.API.Operations.tcAccessPolicyOperationsIntf;  
 import Thor.API.Operations.tcAccessPolicyOperationsIntf.PolicyNLAObjectActionType;  
 //OIM 11g R2 APIs  
 import java.util.Collections;  
 import oracle.iam.accesspolicy.api.AccessPolicyService;  
 import oracle.iam.provisioning.api.ApplicationInstanceService;  
 import oracle.iam.identity.rolemgmt.api.RoleManager;  
 import oracle.iam.identity.rolemgmt.vo.Role;  
 import oim.client.role.ClientRole;  
 import oracle.iam.identity.rolemgmt.api.RoleManagerConstants;  
 import oracle.iam.platform.entitymgr.vo.SearchCriteria;  
 import oracle.iam.platform.entitymgr.vo.SearchRule;  
 import oracle.iam.provisioning.exception.ApplicationInstanceNotFoundException;  
 import oracle.iam.provisioning.exception.GenericAppInstanceServiceException;  
 import oracle.iam.provisioning.vo.ApplicationInstance;  
 import oracle.iam.provisioning.vo.FormField;  
 import oracle.iam.provisioning.vo.FormInfo;  
 public abstract class ClientPolicy extends Client {  
   protected AccessPolicyService _service = null;  
   protected ApplicationInstanceService _appInstanceService = null;  
   protected tcAccessPolicyOperationsIntf _moAccesspolicyutility = null;  
   public RoleManager rmgr;  
   //----------------------------------------------------------------  
   public ClientPolicy() throws Exception  
   //----------------------------------------------------------------  
   {  
     super();  
     //Get all the services instances  
     _service = _oimClientAuthen.getService(AccessPolicyService.class);  
     _moAccesspolicyutility =  
         _oimClientAuthen.getService(tcAccessPolicyOperationsIntf.class);  
     rmgr = _oimClientAuthen.getService(RoleManager.class);  
     _appInstanceService =  
         _oimClientAuthen.getService(ApplicationInstanceService.class);  
     return;  
   }  
   /**  
    * Create Access Policy and return key  
    * @param policyName  
    * @param accessPolicy  
    * @param appInstanceName - Currently code works only for OUD App Instance  
    * @param groupList  
    * @return  
    */  
   public long createAccessPolicy(String policyName, String accessPolicy,  
                   String appInstanceName, List<String> groupList) {  
     long policyKey = 0;  
     try {  
       HashMap<String, String> attr = new HashMap<String, String>();  
       ApplicationInstance appInstance =  
         findApplicationInstanceByName(appInstanceName);  
       //Resource Objects and IT Resource Key and names  
       Long objKey = appInstance.getObjectKey();  
       String objName = appInstance.getObjectName();  
       String itResourceKey =  
         Long.toString(appInstance.getItResourceKey());  
       //Get Parent Form and Child Form  
       FormInfo parentForm = appInstance.getAccountForm();  
       long parentFormKey = parentForm.getFormKey();  
       String parentFormName = parentForm.getName();  
       FormInfo childFormGrp = appInstance.getChildForms().get(0);  
       long childFormGrpKey = childFormGrp.getFormKey();  
       String childFormGrpName = childFormGrp.getName();  
       //Access Policy attributes  
       //Check https://docs.oracle.com/cd/E52734_01/oim/OMJAV/Thor/API/Operations/tcAccessPolicyOperationsIntf.html  
       attr.put("Access Policies.Name", policyName); // Policy Name  
       attr.put("Access Policies.Description", accessPolicy);  
       attr.put("Access Policies.Retrofit Flag", "1"); // Retrofit Flag  
       //Resource Object Key to be provisioned  
       long[] provObjKeys = { objKey };   
       PolicyNLAObjectActionType[] actionIfPolNotApply = { PolicyNLAObjectActionType.REVOKE }; //Revoke If No Longer Applies Flag  
       long[] denyObjKeys = { }; //Object key of Resource to be denied  
       //Populate Parent Form Data  
       HashMap<String, String> parentFormData =  
         new HashMap<String, String>();  
       //Check the process form for the resource object to get the column names  
       //These field names are only applicable for OUD Application Instance  
       parentFormData.put("UD_LDAP_USR_SERVER", itResourceKey);  
       parentFormData.put("UD_LDAP_USR_ORGANIZATION",  
                 itResourceKey + "~" +  
                 "ou=People,dc=idmworks,dc=com");  
       //Set Parent Form Data  
       int groupLength =  
         groupList.size(); // Get the count of the no of groups or entititlements to be provisioned  
       AccessPolicyResourceData policyData[] =  
         new AccessPolicyResourceData[groupLength];  
       String groupPrefix = itResourceKey + "~";  
       //Populate Child Form Data  
       for (int i = 0, j = 0; i < groupLength; i++, j++) {  
         String groupName = groupPrefix + groupList.get(i).trim();  
         System.out.println(groupName);  
         policyData[j] =  
             new AccessPolicyResourceData(objKey, objName, parentFormKey,  
                            parentFormName, "P");  
         policyData[j].setFormData(parentFormData);  
         //Create a map to put child form fields values  
         HashMap childTableMap = new HashMap();  
         //For OUD App Instance - Child   
         childTableMap.put("UD_LDAP_GRP_GROUP_NAME", groupName);  
         policyData[j].addChildTableRecord(Long.toString(childFormGrpKey),  
                          "fChildName", "Add",  
                          childTableMap);  
       }  
       policyKey =  
           _moAccesspolicyutility.createAccessPolicy(attr, provObjKeys,  
                                actionIfPolNotApply,  
                                denyObjKeys,  
                                policyData);  
     } catch (Exception e) {  
       e.printStackTrace();  
     }  
     return policyKey;  
   }  

   /**  
    * Assign access policy to role  
    * @param roleName  
    * @param policyName  
    * @throws Exception  
    */  
   public void assignAccessPolicyToRole(String roleName,  
                      String policyName) throws Exception {  
     SearchCriteria criteria = null;  
     List<Role> roles = Collections.EMPTY_LIST;      
     // Search for roles by role name  
     criteria = new SearchCriteria(RoleManagerConstants.ROLE_NAME, roleName, SearchCriteria.Operator.EQUAL);  
     roles = rmgr.search(criteria, null, null);  
     if (roles.isEmpty()) {  
       System.out.println("Role not found");  
       return;  
     } else {  
       HashMap<String, Object> mapAttrs = new HashMap<String, Object>();  
       //Add the list of access polices to add  
       //Key: "Add" and Value - Access Policy Keys List  
       Map<String, List<String>> accessPoliciesMap =  
         new HashMap<String, List<String>>();  
       List<String> accessPoliciesAddList = new ArrayList<String>();  
       accessPoliciesAddList.add(Long.toString(getAccessPolicyKey(policyName)));  
       accessPoliciesMap.put("ADD", accessPoliciesAddList);  
       mapAttrs.put(RoleManagerConstants.ACCESS_POLICIES,  
              accessPoliciesMap);  
       Role role = new Role(mapAttrs);  
       rmgr.modify(RoleManagerConstants.ROLE_NAME, roleName, role);  
     }  
   }  
   /**  
    * Get Access policy key  
    * @param policyName  
    * @return  
    * @throws Exception  
    */  
   private long getAccessPolicyKey(String policyName) throws Exception {  
     HashMap attributeList = new HashMap();  
     attributeList.put("Access Policies.Name", policyName);  
     long policyKey = 0;  
     tcResultSet result =  
       _moAccesspolicyutility.findAccessPolicies(attributeList);  
     if (!result.isEmpty()) {  
       result.goToRow(0);  
       policyKey = result.getLongValue("Access Policies.Key");  
     }  
     return policyKey;  
   }  
   /**  
    * Find Application Instance By Name  
    * @param applicationInstanceName  
    * @return  
    * @throws ApplicationInstanceNotFoundException  
    * @throws GenericAppInstanceServiceException  
    */  
   private ApplicationInstance findApplicationInstanceByName(String applicationInstanceName) throws ApplicationInstanceNotFoundException,  
       GenericAppInstanceServiceException {  
     ApplicationInstance appInstance =  
       _appInstanceService.findApplicationInstanceByName(applicationInstanceName);  
     return appInstance;  
   }   
 }  






Thursday, December 8, 2016

Angular 2 : Router Guards

The guards are used to protect routes and to check if the navigation is permitted. Sometimes, these are called during the construction of router state or after that. It is used for security and authorization purposes. There are four types of guards -

  • canLoad/ canActivate - Checks if the router can be activated
  • canActivateChild - Similar to canActivate, except that it is called when a child of the route is activated, and not the route itself.
  • canDeactivate - This is different from all others and used for confirmation not permissions. Let's say you want to show confirmation message to user if user try to close the form with unsaved changes.
I am going to discuss in detail about canActivate. canActivate guard decides if route can be activated and it gets executed when navigating to that specific route. canLoad is called during the construction of the Router State and canActivate is called after that. That's the reason canActivate constructor takes router state also as an input but canLoad only takes Route as an input. You can define multiple guards for a route and those are called in the order they are defined in the RouterConfig file.

Here is the simple use case on how to use routing guards. Suppose, you have an application where both admin and normal user can login. There is some content which only admins can see and some which is specific to normal users. But both admin and user need to authenticate first to view any content.  I created one guard to check if the user is authenticated and then created two separate guards for user and admins extending the authentication guard.


Define the routes in the Application Routing file and use the canActivate property to specify the Guard class name.

 export const APP_ROUTES: Routes = [  
   { path: 'admin', component: AdminNavComponent, children: [...ADMIN_ROUTES] ,  
     canActivate: [CanActivateViaAdminGuard]},  
   { path: 'usr', component: UserNavComponent, children: [...USER_ROUTES] ,   
     canActivate: [CanActivateViaUserGuard]},  
 ];  
 export const ROUTING = RouterModule.forRoot(APP_ROUTES);  

Where CanActivateViaAdminGuard and CanActivateViaUserGuard are defined like this -

CanActivateViaAdminGuard

 @Injectable()  
 export class CanActivateViaAdminGuard extends CanActivateViaAuthGuard {  
  constructor(public authService : AuthService, public router: Router) {  
    super(authService, router);  
  }  
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> 
| boolean{  
    //Call CanActivateViaAuthGuard to check if authenticated  
    if(!super.canActivate(route,state)){  
      return false;  
    }  
    else{  
      //Check the user type through authService  
      if(!(this.authService.loggedInUser.type == "admin")){  
       this.router.navigate(['403-not-authorized']);  
       return false;  
      }  
      else{  
        return true;  
      }  
    }  
  }  
 }  

CanActivateViaUserGuard
 @Injectable()  
 export class CanActivateViaUserGuard extends CanActivateViaAuthGuard {  
  constructor(public authService : AuthService, public router: Router) {  
    super(authService, router);  
  }  
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> 
| boolean{  
    if(!super.canActivate(route,state)){  
      return false;  
    }  
    else{  
      if(!(this.authService.loggedInUser.type == "default")){  
       this.router.navigate(['403-not-authorized']);  
       return false;  
      }  
      else{  
        return true;  
      }  
    }  
  }  
 }  

CanActivateViaAuthGuard

 @Injectable()  
 export class CanActivateViaAuthGuard implements CanActivate {  
  constructor(public authService : AuthService, public router: Router) {}  
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean{  
   //Check if user logged in and current url is not login page  
   if (state.url !== '/auth/signin' && !this.authService.isLoggedIn()) {  
       this.router.navigate(['/auth/signin']);  
       return false;  
   }  
   return true;  
  }  
 }  

This is not the only way to implement it. You can also define multiple guards for a route like this -

{ path: 'admin', component: AdminNavComponent, children: [...ADMIN_ROUTES] ,  
     canActivate: [CanActivateViaAuthGuard, CanActivateViaAdminGuard]} 
}

Specify, providers for the guards in the app module file -
 @NgModule({  
 //...  
 providers: [CanActivateViaAdminGuard, CanActivateViaAuthGuard, CanActivateViaUserGuard ]  
 //...  
 })

export class AppModule {

}  

Finally, in the boot.ts file
 platformBrowserDynamic().bootstrapModule(AppModule);