IBM Security Verify

 View Only
  • 1.  Getting the WAS enviroment ISIM_HOME variable into a java script

    Posted Fri April 30, 2021 08:30 AM
      |   view attached

    Hi ISIM colleagues,
    according to the following note,
    Externalizing the java scripts in Identity Manager workflows

    Ibm remove preview
    Externalizing the java scripts in Identity Manager workflows
    How do you extend the functionality of identity manager workflows by externalizing the java scripts in ISIM 7 or Identity Manager 10.0 Virtual Appliance for IBM Security Verify Governance?
    View this on Ibm >



    the java scripts used in ISIM workflows can be externalized.

    There is no doubt it is very useful to avoid to run the plugging when a modification has to be done into a workflow, mainly during the developing phases

    We have tested it and it works perfectly, nevertheless we would like to define the java scripts location based on the ISIM_HOME defined in WAS as an enviroment variable , which is defined during the installation process, its value depends on the enviroment, and it is the best location to store the files. Thus, for promoting new workflow releases from the Development, PreProduction and Production environment without any changes, it is mandatory to taking into consideration the installation path, and so, the script location.

    How can we get the value of the ISIM variable in a java script?

    PS: the environment variables values reachable by java.lang.System.getProperty(), or the operating system variables, java.lang.System.getenv(), don't provide this knowledge.

    Thanks in advance.



    ------------------------------
    Felipe Risalde Serrano
    Security Expert
    Banco de España
    ------------------------------


  • 2.  RE: Getting the WAS enviroment ISIM_HOME variable into a java script

    Posted Mon May 03, 2021 07:15 AM
    Edited by Franz Wolfhagen Mon May 03, 2021 07:15 AM
    This is definitely not an easy task.....

    I can see you have search the web for answers - I wonder if you did check this guideline from the WebSphere documentation : https://www.ibm.com/docs/en/was-nd/8.5.5?topic=servers-creating-editing-deleting-websphere-variables ?

    I played around a little bit and one obstacle you have to solve is to make the adminClient jar(s ?) available to ISIM - they seems to included by default. I played around in SDI and I had problems getting past obtaining the server from WebSphere - there might be a dedicated admin login required to get that outside the WebSphere environment.

    Another obstacle to overcome is the as.invoke() call as it depends on java.lang.Object/String arrays - these are probably a challenge to create within ISIM JavaScript - just to warn you :-)

    I am definitely interested in finding out whether this works out - you may "simply" create the aforementioned function as a JavaScript extension - this might get you around some of the challenges....

    HTH

    ------------------------------
    Franz Wolfhagen
    IAM Technical Architect for Europe - Certified Consulting IT Specialist
    IBM Security Expert Labs
    ------------------------------



  • 3.  RE: Getting the WAS enviroment ISIM_HOME variable into a java script

    Posted Mon May 03, 2021 12:07 PM
    Just to elaborate a little - all the methods are mentioned are available - I had a typo when I tested and draw the wrong conclusion. Right now I am fighting the last
     <Message Id = "Script interpreter error, line=69, col=18: Java method 'invoke(javax.management.ObjectName, java.lang.String, [Ljava.lang.Object;, [Ljava.lang.Object;)' on java class 'com.ibm.ws.management.AdminServiceImpl' not found">

    It looks like my last Array is somehow a java.lang.Object - this is my code :

    importPackage(Packages.com.ibm.websphere.management);
    importPackage(Packages.javax.management);
    importPackage(Packages.org.apache.commons.beanutils);
    
    
    as = AdminServiceFactory.getAdminService();
    server = as.getProcessName();
    Enrole.log("**** WAS TEST ****","server : " + server);
    result = as.queryNames(new javax.management.ObjectName("*:*,type=AdminOperations,process=" + server), null); 
    Enrole.log("**** WAS TEST ****","result : " + result);
    
    myName = new javax.management.ObjectName(result.iterator().next());
    Enrole.log("**** WAS TEST ****","myName : " + myName);
    myOperationName = new java.lang.String("expandVariable");
    //myOperationName = "expandVariable"	;
    //myParams = ["${ITIM_HOME}"];
    myList = new java.util.ArrayList();
    myParam = new java.lang.Object();
    myParam = "${ITIM_HOME}";
    myList.add(myParam);
    myParams = myList.toArray();
    Enrole.log("**** WAS TEST ****","myParams : " + myParams);
    //mySignatures = ["java.lang.String"];
    myList = new java.util.ArrayList();
    mySignature = new java.lang.String("java.lang.String");
    //mySignature = "java.lang.String";
    myList.add(mySignature);
    mySignatures = myList.toArray();
    Enrole.log("**** WAS TEST ****","mySignatures : " + mySignatures);
    
    //myITIM_HOME = as.invoke(myName,myOperationName,myParams,mySignatures);
    //myList = new java.util.ArrayList();
    //myList.add(myName);
    //myList.add(myOperationName);
    //myList.add(myParams);
    //myList.add(mySignatures);
    
    myMethodUtils = new MethodUtils();
    importPackage(Packages.com.ibm.websphere.management);
    importPackage(Packages.javax.management);
    importPackage(Packages.org.apache.commons.beanutils);
    
    
    as = AdminServiceFactory.getAdminService();
    server = as.getProcessName();
    Enrole.log("**** WAS TEST ****","server : " + server);
    result = as.queryNames(new javax.management.ObjectName("*:*,type=AdminOperations,process=" + server), null); 
    Enrole.log("**** WAS TEST ****","result : " + result);
    
    myName = new javax.management.ObjectName(result.iterator().next());
    Enrole.log("**** WAS TEST ****","myName : " + myName);
    myOperationName = new java.lang.String("expandVariable");
    //myOperationName = "expandVariable"	;
    //myParams = ["${ITIM_HOME}"];
    myList = new java.util.ArrayList();
    myParam = new java.lang.Object();
    myParam = "${ITIM_HOME}";
    myList.add(myParam);
    myParams = myList.toArray();
    Enrole.log("**** WAS TEST ****","myParams : " + myParams);
    //mySignatures = ["java.lang.String"];
    myList = new java.util.ArrayList();
    mySignature = new java.lang.String("java.lang.String");
    //mySignature = "java.lang.String";
    myList.add(mySignature);
    mySignatures = myList.toArray();
    Enrole.log("**** WAS TEST ****","mySignatures : " + mySignatures);
    
    myITIM_HOME = as.invoke(myName,myOperationName,myParams,mySignatures);
    //myList = new java.util.ArrayList();
    //myList.add(myName);
    //myList.add(myOperationName);
    //myList.add(myParams);
    //myList.add(mySignatures);
    
    //myMethodUtils = new MethodUtils();
    //myITIM_HOME = myMethodUtils.invokeMethod(as,"invoke",myList.toArray() );
    
    Enrole.log("**** WAS TEST ****","myITIM_HOME : " + myITIM_HOME);
    //myITIM_HOME = myMethodUtils.invokeMethod(as,"invoke",myList.toArray() );
    myITIM_HOME = myMethodUtils.invokeMethod(as,"invoke",[myName,myOperationName,myParams,mySignatures] );
    
    Enrole.log("**** WAS TEST ****","myITIM_HOME : " + myITIM_HOME);
    	


    ------------------------------
    Franz Wolfhagen
    IAM Technical Architect for Europe - Certified Consulting IT Specialist
    IBM Security Expert Labs
    ------------------------------



  • 4.  RE: Getting the WAS enviroment ISIM_HOME variable into a java script

    Posted Tue May 04, 2021 09:57 AM
    I got the script working - but alas no success yet. First - here is the working script :
    importPackage(Packages.com.ibm.websphere.management);
    importPackage(Packages.javax.management);
    as = AdminServiceFactory.getAdminService();
    server = as.getProcessName();
    Enrole.log("**** WAS TEST ****","server : " + server);
    result = as.queryNames(new javax.management.ObjectName("*:*,type=AdminOperations,process=" + server), null); 
    Enrole.log("**** WAS TEST ****","result : " + result);
    myName = new javax.management.ObjectName(result.iterator().next());
    Enrole.log("**** WAS TEST ****","myName : " + myName);
    myOperationName = new java.lang.String("expandVariable");
    myList = new java.util.ArrayList();
    myParam = new java.lang.Object();
    myParam = "${ITIM_HOME}";
    myList.add(myParam);
    myParams = new java.lang.Object[1];
    myParams = myList.toArray(myParams);
    Enrole.log("**** WAS TEST ****","myParams : " + myParams);
    myList = new java.util.ArrayList();
    mySignature = new java.lang.String("java.lang.String");
    myList.add(mySignature);
    mySignatures = new java.lang.String[1];
    mySignatures = myList.toArray(mySignatures);
    Enrole.log("**** WAS TEST ****","mySignatures : " + mySignatures);
    myITIM_HOME = as.invoke(myName,myOperationName,myParams,mySignatures);
    Enrole.log("**** WAS TEST ****","myITIM_HOME : " + myITIM_HOME);​


    Now - it does not return the ITIM_HOME location - in the WAS SystemOut.log I get this error message :

    [5/4/21 13:16:52:199 CEST] 00000046 RoleBasedAuth A   SECJ0305I: The role-based authorization check failed for admin-authz operation AdminOperations:expandVariable:java.lang.String.  The user isimsystem (unique ID: user:itimcustomrealm/isimsystem) was not granted any of the following required roles: operator, administrator.


    This is quite obvious because the workflow is run under isimsystem user but that does not have any administrative userrights in WAS. I have tried to find a way to add those rights - they are not available as part of the default custom User Realm that ISIM uses - I have tried to map (a security overkill....) the wasadmin user to the isimsystem user but still no success - my WAS knowledge is not deep enough to be able to point ta a solution immediately...

    That said - mapping the group Operator to isimsystem should probably not be that big an issue (security wise) - but if you are running the VA this will be impossible as the WAS console and hence changes like this is not possible with IBM support.

    Another possibility is that WAS allows to change the user subject it runs as - i.e a kind of switch user functionality - I have code for ISIM doing that that may allow a switch to the WAS administrative user (may require that to exist as a ISIM user in the ldap - similarly to isimsystem when running java apps methods from the workflow.

    But this the current results of a little tinkering around  - HTH :-)



    ------------------------------
    Franz Wolfhagen
    IAM Technical Architect for Europe - Certified Consulting IT Specialist
    IBM Security Expert Labs
    ------------------------------



  • 5.  RE: Getting the WAS enviroment ISIM_HOME variable into a java script
    Best Answer

    Posted Wed May 05, 2021 11:43 AM
      |   view attached
    Hi Franz,
    thanks for your great and valuable effort.

    I have got in contact with our WAS administrators to know their oppinions regarding this issue. They suggest us to generate variables linked to the Java Virtual Machine (JVM) of the Application servers - they can be recovered by java.lang.System.getProperty() function- since to recover the ISIM_HOME isn't an easy tasks (as you are suffering).

    Having a look this approach, we've realized that, although it isn't the ISIM_HOME value, it's easy to obtain from the 'javax.net.ssl.trustStore' variable which it is always defined during ISIM instalación, ie, it isn't needed to define custom ones.

    Thus, the easier approach is to use this variable, or, to define new one. It's up to you

    var myCodePath = java.lang.System.getProperty("javax.net.ssl.trustStore");

    var myCodePath= myCodePath.substring(0,myCodePath.indexOf("/cert"))+"/data/WK-scripts";

     

    // Open the external JavaScript file

    var myScriptFile = new java.io.BufferedReader(new java.io.FileReader(myCodePath + "/Person-Person-Add_AnadirRoles.java"));

     

    var myLineOfCode = null;

    var myCode = "";

     

    // Read the file and add each line of code we find to a variable

    while ((myLineOfCode = myScriptFile.readLine()) != null) {

                myCode += myLineOfCode+'\n';

    }

     

    // Close the file

    myScriptFile.close();

    // Execute the code that we have gathered together

    eval(myCode);


    (For future references) Working in ISIM 6.0 it's needed to include
    ITIM.java.access.lang=java.lang.*
    in the scriptframework.properties file.

    ------------------------------
    Felipe Risalde Serrano
    Security Expert
    Banco de España
    ------------------------------



  • 6.  RE: Getting the WAS enviroment ISIM_HOME variable into a java script

    Posted Wed May 05, 2021 03:54 PM
    Yeah - it is not easy to give access to the WAS environment from inside ISIM - but I have a good reason for trying to do this - if you have an adapter using ISIM APPS API and you do not want to go through a lot of problems setting up the SDI environment for that it would be nice being able to provide all that automagically from ISIM - and that requires to read the WAS setup to be 100% accurate - of course you can use tricks like the javax truststore (I am actually not sure that it is setup in non-clustered environments - in older times this was one of the main differences between clustered and non-clustered).

    I have tried to create a WAS group containing the Administrator and Operator role and assign that group to the ISIM SYSTEM role - but it still does not allow me to perform WAS administrative task - I will need to check with some WAS guru what the procedure should be...

    The general problem of where to store information about the environment there are many possibilities - an external maintained piece of data can reside many places - DB, LDAP and WAS (and a property) - btw - ISIM has its own PropertyManager class that also allows handling of encrypted properties - it should be part of the documented APIs in the newer releases - you can find examples of it in many of the ISIM JAVA samples flowing around on the web.
     
    I like your goal of externalizing javascript - but it comes with some considerations - it would be better if there was a protected path where you could store the scripts (accessible with REST for automatic maintenance/integration with version control repositories).

    One small comment - you are using the eval() function - this is potentially dangerous if any of the string that is going in there is coming from user input - if - then you basically open up the system completely (there is only the script used in your code - and that is hopefully trusted code) - so be careful :-)

    And let the challenges come - it is always fun to try to solve real riddles :-)

    ------------------------------
    Franz Wolfhagen
    IAM Technical Architect for Europe - Certified Consulting IT Specialist
    IBM Security Expert Labs
    ------------------------------