Search This Blog

Monday 9 September 2019

Java Code to Decrypt User Password and Fetch Security Question and Answers in OIM

OIM does not allow to Decrypt user password from User form now. So, as a workaround, we can fetch the password from Process form and Decrypt it using the below code:

package Retry_Failed;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.security.auth.login.LoginException;

import com.thortech.xl.dataaccess.tcDataBaseClient;
import com.thortech.xl.dataaccess.tcDataProvider;
import com.thortech.xl.dataaccess.tcDataSet;

import Thor.API.tcResultSet;
import Thor.API.Operations.tcFormInstanceOperationsIntf;
import Thor.API.Operations.tcUserOperationsIntf;
import Thor.API.Security.XLClientSecurityAssociation;
import oracle.iam.platform.OIMClient;
import oracle.iam.provisioning.api.ProvisioningService;
import oracle.iam.provisioning.vo.Account;

public class Decrypt

{
private static OIMClient oimClient;



public static void init() throws LoginException {
String hostName = "oim_hostname";
String port = "oim_port_no";
System.out.println("Creating client....");
String ctxFactory = "weblogic.jndi.WLInitialContextFactory";
String serverURL = "t3://" + hostName + ":" + port;
String username = "xelsysadm";
String password = "xelsysadm_Password";

System.setProperty("java.security.auth.login.config",
"Location of Local authwl.comf");
System.setProperty("APPSERVER_TYPE", "wls");
Hashtable env = new Hashtable();
env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL, ctxFactory);
env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, serverURL);

oimClient = new OIMClient(env);
System.out.println("Logging in");

oimClient.login(username, password);
System.out.println("Log in successful");

}

public static void main(String args[]) throws Exception
{
init();
tcDataProvider dbProvider = null;
String userLogin = null;
Map<String, String> challengeQuestionAnswer = new HashMap<String, String>();
XLClientSecurityAssociation.setClientHandle(oimClient);//Needed for database client
        dbProvider = new tcDataBaseClient(); //Connection to OIM Schema
        tcDataSet dataSet = new tcDataSet(); //Stores the result set of an executed query
       
        tcDataSet dataSet_PCQ = new tcDataSet(); //Stores the result set of an executed query

        String query = "SELECT * FROM USR where USR_LOGIN in UPPER('USR_LOGIN of User to Decrypt password For')";

        dataSet.setQuery(dbProvider, query); //Set query and database provider
        dataSet.executeQuery(); //execute query and store results into dataSet object
        int records = dataSet.getTotalRowCount();
        String usr_key="";
        for(int i = 0; i < records; i++)
        {
            dataSet.goToRow(i); //move pointer to next record
            usr_key = dataSet.getString("USR_KEY");
//            String decryptPwd = tcCryptoUtil.decrypt(encPwd,"DBSecretKey");
            userLogin = dataSet.getString("USR_LOGIN");
            String userStatus = dataSet.getString("USR_STATUS");
            System.out.printf("User Login: %s\nStatus: %s\nKey: %s\n\n", userLogin, userStatus, usr_key);
//            System.out.printf("User Login: %s\nStatus: %s\nPassword: %s\n\n", userLogin, userStatus, decryptPwd); 
           
           
           
     
        }
       
//        }
        challengeQuestionAnswer = getChallengeQuesAns(usr_key);
        for (Entry<String, String> entry : challengeQuestionAnswer.entrySet()) {
System.out.println("Question : "+entry.getKey()+" Answer : "+entry.getValue());
}
long procInstKey = getProcessInstKeyOfRes("LDAP User", usr_key, new String[] { "Provisioned", "Enabled" }, oimClient, userLogin);
    String passkey = getLDAPPassword(oimClient, procInstKey);
    System.out.println("Entering into password:: " + passkey);
}


private static Map<String, String> getChallengeQuesAns(String usr_key) {
Map<String, String> challengeQuestionAnswers = new HashMap<String, String>();
try

{

tcUserOperationsIntf userOperationsIntf = (tcUserOperationsIntf) oimClient

.getService(tcUserOperationsIntf.class);

tcResultSet resultSet = userOperationsIntf

.getChallengeValuesForUser(Long.parseLong(usr_key));

if ((resultSet == null) || (resultSet.isEmpty())) {

System.out.println("ResultSet is Empty or null");

return challengeQuestionAnswers;

}

int rowCount = resultSet.getRowCount();

for (int j = 0; j < rowCount; j++) {

resultSet.goToRow(j);

String[] columnNames = resultSet.getColumnNames();

for (int i = 0; i < columnNames.length; i++) {

String question = resultSet.getStringValue("Users.Password Challenge Question.Question");

String answer = resultSet.getStringValue("Users.Password Challenge Question.Answer");

challengeQuestionAnswers.put(question, answer);

}

}

} catch (Exception e) {

e.printStackTrace();

}
return challengeQuestionAnswers;
}


public static long getProcessInstKeyOfRes(String res_Name, String userkey, String[] statusArray, OIMClient oimClient, String userLogin)
  throws Exception
{
  long longProcessInstanceKey = 0L;
  String methodName = "getProcessInstKeyOfRes():::";
 
  ProvisioningService ps = (ProvisioningService)oimClient.getService(ProvisioningService.class);
  try
  {
    System.out.println(methodName + "Entering into method:: " + methodName);
   
    List<Account> userAccount = ps.getAccountsProvisionedToUser(userkey);
    System.out.println(methodName + "size of list--->" + userAccount.size());
    System.out.println(userAccount);
   
   
    for (Account account : userAccount) {
//    System.out.println(account.getAppInstance()+"\n"+account.getAccountDescriptiveField());
//    account.get
//      if ((account.getAppInstance().toString().contains("Enterprise")) || (account.getAppInstance().toString().contains("ODSEE"))) {
    if (account.getAppInstance().toString().contains("ODSEE") && account.getAccountDescriptiveField().toString().contains(userLogin)){
        if ((Arrays.asList(statusArray).contains(account.getAccountStatus().toString())) && (account.getAccountType().toString().equalsIgnoreCase("Primary")))
        {
          System.out.println(methodName + " >>>>>> account.getAccountType() " + account.getAccountType());
          System.out.println(methodName + " >>>>>> account.getAccountStatus() " + account.getAccountStatus());
          System.out.println(methodName + " >>>>>> account.getProcessInstanceKey() " + account.getProcessInstanceKey());
          longProcessInstanceKey = Long.parseLong(account.getProcessInstanceKey().toString());
        }
      }
    }
    System.out.println(methodName + "longProcessInstanceKey --->" + longProcessInstanceKey);
  }
  catch (Exception e)
  {
    System.out.println(methodName + ".START().ERROR()-> " + e.getMessage());
    throw new Exception("ERROR");
  }
  return longProcessInstanceKey;
}



public static String getLDAPPassword(OIMClient oimClient, long procInstKey)
  throws Exception
{
  String ldapPassword = null;
  String methodName = "getLDAPPassword():::";
  String usrID = null;
  try
  {
    System.out.println(methodName + "Entering into method:: " + methodName);
    if (procInstKey > 0L)
    {
      tcFormInstanceOperationsIntf formInstanceOperationsIntf = (tcFormInstanceOperationsIntf)oimClient.getService(tcFormInstanceOperationsIntf.class);
      tcResultSet resultSet = formInstanceOperationsIntf.getProcessFormData(procInstKey);
      int rowCount = resultSet.getRowCount();
      System.out.println(methodName + "rowCount = " + rowCount);
      for (int j = 0; j < rowCount; j++)
      {
        resultSet.goToRow(j);
       
        ldapPassword = resultSet.getStringValue("UD_LDAP_USR_PASSWORD");
       
        usrID = resultSet.getStringValue("UD_LDAP_USR_USERID");
      }
    }
    System.out.println(methodName + "usrID = " + usrID);
    System.out.println(methodName + "Exiting method:: " + methodName);
  }
  catch (Exception e)
  {
    System.out.println(methodName + ".START().ERROR()-> " + e.getMessage());
    throw new Exception("ERROR");
  }
  return ldapPassword;
}


}

Tuesday 14 May 2019

Java Code to Connect to Active Directory and fetch details

package ActiveDirectoryConnect;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;


public class ADTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws NamingException {
     
        final String AdServer = "ldap://ad.your-server.com:389";
        final String ADSearchBase = "dc=ad,dc=my-domain,dc=com";
     
        final String ADUsername = "myADUsername";
        final String ADPassword  = "myADPassword ";
     
        final String ADAccountToLookup  = "myOtherADUsername";
     
     
        Hashtable<String, Object> env = new Hashtable<String, Object>();
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        if(ADUsername != null) {
            env.put(Context.SECURITY_PRINCIPAL, ADUsername);
        }
        if(ADPassword  != null) {
            env.put(Context.SECURITY_CREDENTIALS, ADPassword );
        }
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, AdServer);

        //ensures that objectSID attribute values
        //will be returned as a byte[] instead of a String
        env.put("java.naming.ldap.attributes.binary", "objectSID");
     
        // the following is helpful in debugging errors
        //env.put("com.sun.jndi.ldap.trace.ber", System.err);
     
        LdapContext ctx = new InitialLdapContext(env, null);
     
        ADTest ldap = new ADTest();
     
        //1) lookup the ldap account
        SearchResult srLdapUser = ldap.findAccountByAccountName(ctx, ADSearchBase, ADAccountToLookup );
     
        //2) get the SID of the users primary group
        String primaryGroupSID = ldap.getPrimaryGroupSID(srLdapUser);
     
        //3) get the users Primary Group
        String primaryGroupName = ldap.findGroupBySID(ctx, ADSearchBase, primaryGroupSID);
    }
 
    public SearchResult findAccountByAccountName(DirContext ctx, String ADSearchBase, String accountName) throws NamingException {

        String searchFilter = "(&(objectClass=user)(sAMAccountName=" + accountName + "))";

        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

        NamingEnumeration<SearchResult> results = ctx.search(ADSearchBase, searchFilter, searchControls);

        SearchResult searchResult = null;
        if(results.hasMoreElements()) {
             searchResult = (SearchResult) results.nextElement();

            //make sure there is not another item available, there should be only 1 match
            if(results.hasMoreElements()) {
                System.err.println("Matched multiple users for the accountName: " + accountName);
                return null;
            }
        }
     
        return searchResult;
    }
 
    public String findGroupBySID(DirContext ctx, String ADSearchBase, String sid) throws NamingException {
     
        String searchFilter = "(&(objectClass=group)(objectSid=" + sid + "))";

        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
     
        NamingEnumeration<SearchResult> results = ctx.search(ADSearchBase, searchFilter, searchControls);

        if(results.hasMoreElements()) {
            SearchResult searchResult = (SearchResult) results.nextElement();

            //make sure there is not another item available, there should be only 1 match
            if(results.hasMoreElements()) {
                System.err.println("Matched multiple groups for the group with SID: " + sid);
                return null;
            } else {
                return (String)searchResult.getAttributes().get("sAMAccountName").get();
            }
        }
        return null;
    }
 
    public String getPrimaryGroupSID(SearchResult srLdapUser) throws NamingException {
        byte[] objectSID = (byte[])srLdapUser.getAttributes().get("objectSid").get();
        String strPrimaryGroupID = (String)srLdapUser.getAttributes().get("primaryGroupID").get();
     
        String strObjectSid = decodeSID(objectSID);
     
        return strObjectSid.substring(0, strObjectSid.lastIndexOf('-') + 1) + strPrimaryGroupID;
    }
 

    public static String decodeSID(byte[] sid) {
     
        final StringBuilder strSid = new StringBuilder("S-");

        // get version
        final int revision = sid[0];
        strSid.append(Integer.toString(revision));
     
        //next byte is the count of sub-authorities
        final int countSubAuths = sid[1] & 0xFF;
     
        //get the authority
        long authority = 0;
        //String rid = "";
        for(int i = 2; i <= 7; i++) {
           authority |= ((long)sid[i]) << (8 * (5 - (i - 2)));
        }
        strSid.append("-");
        strSid.append(Long.toHexString(authority));
     
        //iterate all the sub-auths
        int offset = 8;
        int size = 4; //4 bytes for each sub auth
        for(int j = 0; j < countSubAuths; j++) {
            long subAuthority = 0;
            for(int k = 0; k < size; k++) {
                subAuthority |= (long)(sid[offset + k] & 0xFF) << (8 * k);
            }
         
            strSid.append("-");
            strSid.append(subAuthority);
         
            offset += size;
        }
     
        return strSid.toString(); 
    }
}