sion

Oracle Fusion Middleware : Oracle Identity and Access Management Suite 10g/11gR1/11gR2PS1,PS2,PS3 : OIM | OAM,OAAM,OIF | OID, OVD, DIP | OUD/ ODSEE | Microsft AD | OpenLDAP | ADF | EBS R12 | OECMCCR4 | Business Intelleigence - Bi Publisher | Banking | Demo Applications | Core Java | SQL | PLSQL | Web services | Weblogic | Tomcat | JBoss | OHS | WebGate | WebCenter | In any Queries please Contact Me : info@oratechsoft.com

Search This Blog

Thursday, 20 August 2015

A Tour of Oracle Privileged Account Manager

A Tour of Oracle Privileged Account Manager

Usage management of sensitive accounts of LDAP, Database, Linux or custom applications using Oracle Privileged Account Manager 11gR2PS1

Downloads:

Overview:

Oracle Privileged Account Manager is a new product added in the Oracle Identity Management 11gR2 release. As its name suggests, it deals with the management of privileged accounts. By the word “privileged account” we mean that these accounts can access the sensitive data in the organization. Following are the examples of the privileged accounts:
  • Unix root account
  • Database SYSDBA / SYSOPER accounts
  • Windows Administrator accounts
  • Application accounts which access sensitive information
  • System Administrator accounts
Oracle Privileged Account Manager provides an easy to implement and versatile solution for managing high risk accounts. It lets you manage the password policies and the usage policies (e.g. time duration for which you can use the account) for the accounts. It leverages Identity Connector Framework to integrate with third party applications which are supported out of the box. It supports the break the glass facility where one person performs the tasks of another person in case the person is not available due to some emergency. One of the highlighting features is the ability of OPAM to provide comprehensive auditing and reporting of who has acted on a particular account at certain point in time as well as the real time data. It can be combined with Oracle BI Publisher to generate reports. Figure 1 shows the overall architecture of OPAM.



Figure 1
There are two ways in which you can access the Oracle Privileged Account Manager features: Graphical User Interface (GUI) and Command Line Interface (CLI). The latter can be extended to invoke all CLI supported operations through Java API which is given this post. The GUI and CLI interact with the Oracle Privileged Account Manager Server over REST services. The OPAM Server is a component that handles password requests, generates passwords, and protects the password keystore. Figure 2 shows the GUI, CLI and other clients communicate with OPAM using the RESTful interface.



Figure 2

Authentication:

 The authentication framework of the Oracle Privileged Account Manager leverages SAML based token authentication. It can be integrated with Oracle Access Manager Single Sign On. OPAM CLI Supports HTTP Basic Authentication over SSL to connect to OPAM Server.

Authorization:

 There are several Admin Roles supported by OPAM to restrict the sensitive usage of the application:
  • Application Configurator – OPAM_APPLICATION_CONFIGURATOR
  • Security Administrator – OPAM_SECURITY_ADMIN
  • Security Auditor – OPAM_SECURITY_AUDITOR
  • User Manager – OPAM_USER_MANAGER

Administration:


1.     Targets:

A target in OPAM is a system which contains users, and relies on users, system, or application accounts. You need to register the target system in order to manage the accounts associated with the target.  Currently as of release 11.1.2.1.0 OPAM supports four types of pre-built targets. You can see the four supported targets in Figure 3.



Figure 3
Generally adding a target involves providing the values of the host, port, domain and other minimum useful information required to retrieve the accounts from the target system. The two targets needs extra attention - The database target is supported for Oracle, MSSQL, MYSQL, DB2 and Sybase. Lockbox allows us to manage a specific target without configuring any connector.

2.     Accounts:

An account represents the privileged account on a target system. OPAM does not create or delete accounts on the target system; it only manages the existing accounts. When a new account is added in OPAM server, only a reference to that account gets created. Deletion of account from OPAM does not delete the account from the target. OPAM enables you to specify whether an account is shared or not shared. Shared accounts enable multiple users to use the account at the same time. Default (unshared) accounts can be used by only one user at a time. Below Figure 4 shows the database accounts containing the word sys in a database target.



Figure 4

3.     Grantee:

Grantees are users or groups that have been granted access to one or more privileged accounts. Users or groups are assigned to a privileged account in the Account tab. As you can see in Figure 5, user.0 is a grantee for the account DEVOAM_OPAM and there is no group specified.



Figure 5

4.     Check out and Check in:

Administrators or end users can check out an account if they have been granted access to that account. When a user checks out an account, by providing a comment, it gets the access to the password of the account. The password is generated based on the Password Policy attached to the privileged account. On successful checking out, unshared accounts become unavailable for other users to check out until the account is checked in again by the user. Checking in of account resets the password of the account. In case of shared accounts, the password is reset only when all the users check in the account. Figure 6 shows that the accounts which are granted to the logged in user are checked in and ready to be checked out.



Figure 6

5.     Password Policies:

The password policies capture the password construction rules enforced by a specific target on an associated privileged account. Every privileged account must have an associated password policy. OPAM provides Default Password Policy. However you can create custom password policies as per your requirements.

6.     Usage Policies:

The usage policies define when and how a privileged account can be used by a grantee. These are applied at the level of a grant. OPAM provides Default Usage Policy. However you can create custom usage policies as per your requirements.

7.     Reports:

The reports provide the real time information about the status of accounts and targets being managed by OPAM. OPAM provides support for 3 types of reports:
  • Deployment Reports : View information about how targets and privileged accounts are currently deployed
  • Usage Reports : View information about how privileged accounts are currently being used in the deployment
  • Failure Reports : View information about current state of target and account failures

8.     ICF Connectors:

Connectors enable OPAM to interact with the third party target systems. OPAM leverages connectors that are compliant with the ICF standard. OPAM can use custom connectors to interact with the target systems other than the traditional LDAP, database and UNIX system. After the connector is developed and ready to be integrated with OPAM, the connector bundle needs to be put in a location where OPAM can access it at runtime. All the connector related configurations are stored in the file ORACLE_HOME/opam/config/opam-config.xml which schematically is governed by ORACLE_HOME/opam/config/opam-config.xsd. If you have made correct <connectorConfig> entries in opam-config.xml, you will see the new target in the Target dropdown after the server is restarted.

Command Line Interface:

Oracle Privileged Account Manager lets you interact with the OPAM server via HTTP Basic Authentication over SSL. You can perform certain tasks via command line which you can do via GUI. CLI can be launched by ORACLE_HOME/opam/bin/opam.sh (UNIX) or ORACLE_HOME/opam/bin/opam.bat (Windows) . Supported commands are - addaccount, addtarget, checkin, checkout, displayallaccounts, displayallgroups, displayalltargets, displayallusers, displaycheckedoutaccounts, displaydomaintree, displaytargettypetree, grantgroupaccess, grantuseraccess, removeaccount, removegroupaccess, removetarget, removeuseraccess, retrieveaccount, retrievegrantees, retrievegroup, retrievetarget, retrieveuser, searchaccount, searchgroup, searchtarget, searchuser, showpassword
Following command shows an example of how to issue addaccount command:
-url https://hostname:sslport/opam -u <username> [-p <password>] [debug] -x addtarget -targetname <targetname> -host <hostname> -port 22 -organization <organization>

Interacting with RESTful Interface:

OPAM Server has exposed certain RESTful interfaces which are consumed by the GUI and also can be incorporated with other applications which provide the ability to consume REST services. Using RESTful interface of OPAM, you can perform several operations on Targets, Accounts, Users, Groups, Password and Usage Policies. Following is the Java code sample showing the basic REST operations that you can perform:
OPAMRestClient.java

package com.mycompany.opam.demo.rest.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import org.apache.commons.codec.binary.Base64;

/**
 * @author Ganesh
 *
 */
public class OPAMRestClient {

        /**
         * @param args
         */
        public static void main(String[] args) {
                OPAMRestClient client = new OPAMRestClient();
                client.authAndGet();
                client.checkOutAccount();
                client.checkInAccount();
        }

        private void authAndGet() {
                String webPage = "https://192.168.1.31:18102/opam/";
                String result = execute(webPage, "opamadmin", "welcome1", "GET");
                System.out.println("*** RESULT ***");
                System.out.println(result);
        }

        private void checkOutAccount() {
                String webPage = "https://192.168.1.31:18102/opam/account/3a32f71b320645f7b9b594fc8e864089/checkout";
                String result = execute(webPage, "user.0", "welcome1", "PUT");
                System.out.println("*** RESULT ***");
                System.out.println(result);
        }

        private void checkInAccount() {
                String webPage = "https://192.168.1.31:18102/opam/account/3a32f71b320645f7b9b594fc8e864089/checkin";
                String result = execute(webPage, "user.0", "welcome1", "PUT");
                System.out.println("*** RESULT ***");
                System.out.println(result);
        }

        /**
         * @param webPage
         * @return
         * @throws MalformedURLException
         * @throws IOException
         */
        private String execute(String webPage, String name, String password,
                        String requestMethod) {
                String authString = name + ":" + password;
                System.out.println("auth string: " + authString);
                byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
                String authStringEnc = new String(authEncBytes);
                System.out.println("Base64 encoded auth string: " + authStringEnc);

                URL url;
                HttpsURLConnection httpsCon = null;
                String result = null;
                try {
                        url = new URL(webPage);
                        httpsCon = (HttpsURLConnection) url.openConnection();
                        httpsCon.setRequestMethod(requestMethod);
                        httpsCon.setHostnameVerifier(new HostnameVerifier() {
                                @Override
                                public boolean verify(String hostname, SSLSession session) {
                                        return true;
                                }
                        });
                        httpsCon.setRequestProperty("Authorization", "Basic "
                                        + authStringEnc);
                        httpsCon.connect();
                        InputStream is = httpsCon.getInputStream();
                        InputStreamReader isr = new InputStreamReader(is);

                        int numCharsRead;
                        char[] charArray = new char[1024];
                        StringBuffer sb = new StringBuffer();
                        while ((numCharsRead = isr.read(charArray)) > 0) {
                                sb.append(charArray, 0, numCharsRead);
                        }
                        result = sb.toString();
                } catch (MalformedURLException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                } finally {
                        if (httpsCon != null) {
                                httpsCon.disconnect();
                        }
                }
                return result;
        }
}

Integration with Oracle Identity Management solutions:

Oracle Privileged Account Manager can be integrated with Oracle Identity Governance, Oracle Access Management and Oracle Directory Services – the three building tiers of Oracle Identity Management Suite. OPAM provides the ability to manually request access to accounts and to get approvals for requests in Oracle Identity Manager. OPAM can be protected by enabling Single Sign On using a Webgate agent in Oracle Access Manager.

Backend:

Following is a list of tables from DEV_OPAM schema used by the Oracle Privileged Account Manager:
TARGET, ACCOUNT, GRANTS, USGPOL, PWDPOL, FAILURE, ACTSESSION, FLEXFIELD, FLEXOBJ, FLEXSECFIELD
The Metadata information and passwords managed by OPAM are encrypted and persisted in the Oracle Database. It is recommended to leverage Oracle Database Vault and Transparent Data Encryption (TDE) for additional security.

Conclusion:

Oracle Privileged Account Manager is a complete product which has a comprehensive set of features that are required to manage the password lifecycle of privileged accounts – an  activity for which there was no solution available earlier. OPAM delivers more value when used in conjunction with other Oracle Identity Management Products.

References:

OID Policystore Migration

OID Policystore Migration



                 Policystore is basically a node in the hierarchical structure of Oracle Internet Directory where all the application policies are stored. There will be cases where you will want to replicate the policystore structure to some other OID instance in development or in production mode. This is useful in cases where you want to maintain the same application policies across multiple environments. Of course you can use the same OID across different environments but it will be very difficult for troubleshooting
                 OID provides few set of commands using which a policystore can be exported to an LDIF file and then that LDIF file can be imported on another OID.
                 This blog explains the use of ldifwrite and bulkload commands which are used to export the policystore or to be specific any node to an LDIF file and import the LDIF file respectively.
                 Following environment variables must be set before proceeding:
  1. WLS_HOME=<path_where_middleware_is_installed>
  2. ORACLE_HOME=$WLS_HOME/Oracle_IDM1
  3. ORACLE_INSTANCE=$ORACLE_HOME/asinst_1
                 Following directories must be added to the PATH variable:
  1. ORACLE_HOME/bin
  2. ORACLE_HOME/ldap/bin
  3. ORACLE_INSTANCE/bin
                OID instance must be shut down before performing bulkload commands to avoid any inconsistencies in the loading.
                    opmnctl stopall

                Follow the below steps to replicate a node in one OID to another :
  • Use ldifwrite to export a node to an ldif file :
        ldifwrite connect="connect_string" basedn="source_dn" file="location.ldif"
     e.g. If you want to export 'cn=mynode,cn=jpsContext,cn=jpsroot' (basedn)  which resides in ODS schema of OIDDB_SOURCE (connect_string as specified in ORACLE_INSTANCE/config/tnsnames.ora) to a file source.ldif which is at location (/u01/export/source.ldif), use the following command :
        ldifwrite connect="OIDDB_SOURCE" basedn="cn=mynode,cn=jpsContext,cn=jpsroot" file="/u01/export/source.ldif"
  • Use bulkload to import the ldif file and generate the intermediate SQL*Loader files :
      bulkload connect="connect_string" check="true" generate="true" recover="true" file="location.ldif"
     e.g. Intermediate SQL*Loader files which are to be executed for ODS schema in OIDDB_TARGET (connect_string) can be generated from /u01/export/source.ldif (file) with the following command :
          bulkload connect="OIDDB_TARGET" check="true" generate"true" recover="true" file="/u01/export/source.ldif"

              check flag parses and verifies the input LDIF file to find any corrupt data
              generate flag generates the intermediate files in SQL*Loader format
              restore flag restores the schema in case any problem arises during bulkload operation
  • Use bulkload to load the intermediate SQL*Loader files in the target OID schema :
       bulkload connect="connect_string" load="true"
      e.g. Intermediate files generated by 2 option can be loaded in the schema OIDDB_TARGET by the following command :
           bulkload connect="OIDDB_TARGET" load="true"

   After the completion of bulkload execution, start the OID server instance:
                 opmnctl startall

  The logs file generated by the bulkload tool are at location :
        ORACLE_INSTANCE/diagnostics/logs/OID/tools
  1. bulkload.log : output log
  2. duplicateDN.log : list of duplicate DNs found during loading
  3. *.ctl and *.dat : intermediate files
        ORACLE_INSTANCE/OID/load
  1. badentry.ldif : list of bad LDIF entries
  2. dynGrp.ldif : list of dynamic group entries that can be added using ldapadd command
  3. bsl_*.log : intermediate log files generated by SQL*Loader
      If there are any errors during indexing phase of loading, following command can re-create the indices :
           bulkload connect="OIDDB_TARGET" index="true"
      Indices can be verified by using the command :
              bulkload connect="OIDDB_TARGET" check="true" index="true"

     In this way you can migrate the application policystore or any node for that matter from one OID instance to another. The detailed explanation of all the attributes used in the above commands can be found at the location http://docs.oracle.com/cd/E25054_01/oid.1111/e10029/bulktools.htm

OID Performance Tuning

OID Performance Tuning



Oracle Internet Directory is highly scalable and manageable in terms of performance tuning as per the hardware resources and high availability configurations.
In this blog I will explain the parameters which can improve the performance of OID.

1. Database Parameters:
                                Recommended values
sga_target,sga_max_size            upto 60-70% of the available
                                   RAM for database machine
db_cache_size                    upto 60-70% of the available 
                                   RAM for database machine
shared_pool_size                  500M
session_cached_cursors            100
processes                        500
pga_aggregate_target              1-4GB
job_queue_processes               1 or more
max_commit_propagation_delay       99 or lower


2. LDAP Server Attributes:
                                  Recommended values
orclmaxcc                        10 - Number of DB Connections 
                                   per Server Processes
orclserverprocs                   4 - Number of OID LDAP Server 
                                   Processes which should be 
                                   equal to the number of cpu 
                                   cores on the system
orclgeneratechangelog             0 - Disables change log 
                                   generation
orclldapconntimeout               60 - LDAP Connection Timeout
orclmatchdenabled                 0 - Enable MatchDN Processing



3. OID Authenticator Parameters:
    If you have configured Oracle Internet Directory Authenticator in myrealm to retrieve users from OID, following parameters can be changed to optimize the performance:
                                            
                                   Recommended values
Group Membership Searching         limited
Connection Pool Size              120
Connect Timeout                  120
Cache Size                       51200
Cache TTL                        300

4. jps-config Parameters

    If the weblogic server is reassociated to an OID and the application policies are stored in it, following parameters should be added in policystore.ldap serviceInstance in jps-config.xml to make the retrieval of policies faster by caching them.

    <property name="oracle.security.jps.policystore.rolemember.cache.type" value="STATIC"/>
    <property name="oracle.security.jps.policystore.rolemember.cache.strategy" value="NONE"/>
    <property name="oracle.security.jps.policystore.rolemember.cache.size" value="100"/>
    <property name="oracle.security.jps.policystore.policy.lazy.load.enable" value="true"/>
    <property name="oracle.security.jps.policystore.policy.cache.strategy" value="NONE"/>
    <property name="oracle.security.jps.policystore.policy.cache.size" value="1000000"/>
    <property name="oracle.security.jps.policystore.refresh.enable" value="true"/>
    <property name="oracle.security.jps.policystore.refresh.purge.timeout" value="43200000"/>
    <property name="oracle.security.jps.ldap.policystore.refresh.interval" value="6000000"/>
    <property name="oracle.security.jps.policystore.rolemember.cache.warmup.enable" value="true"/>
    <property name="connection.pool.min.size" value="120"/>
    <property name="connection.pool.max.size" value="120"/>
    <property name="connection.pool.provider.type" value="IDM"/>
    <property name="connection.pool.timeout" value="300000"/>
    <property name="connection.pool.provider.type" value="5"/>

   OID and weblogic server restarts are required after modifying the above parameters. They can still be optimized depending on the availability of the hardware resources.
   Ref : http://docs.oracle.com/cd/E23943_01/core.1111/e10108/oid.htm

How to invoke secured JAX-WS web service from a standalone client

How to invoke secured JAX-WS web service from a standalone client


     
       In this post I will explain the procedure of invoking secured JAX-WS web service from a standalone java client. It explains the problems you may face during the process.
There are several ways by which you can invoke a secured web service. I will explain it in two ways here. In this example I have a sample web service which is protected by the policy : wss_saml_or_username_token_service_policy.
I will not get the desired response if I try to invoke the protected web service without providing a proper username token in the soap header.
In weblogic, you can attach policies to web services with the help of owsm. Following block shows the snippet to be present in the soap header in order to get the client asserted by the web service provider which is protected by wss_saml_or_username_token_service_policy policy :

<S:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" S:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-Kr9QjWbqpQgxYI4CDWNxCg22">
<wsse:Username>administrator</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Passw0rd</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</S:Header>

The username in this case is 'administrator' and password is 'Passw0rd'

Here are the two ways in which you can add the above block in the header of the soap request on the client side :
1. First way is to add credentials in the RequestContext of the client port :

      List<CredentialProvider> credProviders =
          new ArrayList<CredentialProvider>();
      String username = "administrator";
      String password = "Passw0rd";
      CredentialProvider cp =
          new ClientUNTCredentialProvider(username.getBytes(),
                                          password.getBytes());
      credProviders.add(cp);
      Map<String, Object> requestContext =
          ((BindingProvider)sampleWebServicePort).getRequestContext();
      requestContext.put(BindingProvider.USERNAME_PROPERTY,username);
      requestContext.put(BindingProvider.PASSWORD_PROPERTY,password);
      sampleWebServicePort.callService();
   

2.  Second way is add to create the soap security header object which is to be added in the HandlerChain :

        try {
            CustomSOAPHandler sh = new CustomSOAPHandler();
            List<Handler> new_handlerChain = new ArrayList<Handler>();
            new_handlerChain.add(sh);
            ((BindingProvider)sampleWebServicePort).getBinding().setHandlerChain(new_handlerChain);
sampleWebServicePort.callService();
        } catch (Throwable e) {
            e.printStackTrace();
        }

Create a custom SOAPHandler class which will add the header in the soap request.
CustomSOAPHandler:


public class CustomSOAPHandler implements SOAPHandler<SOAPMessageContext> {

    private static final String AUTH_PREFIX = "wsse";
    private static final String AUTH_NS =
        "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
.
.
.


    public boolean handleMessage(SOAPMessageContext context) {

        try {
            SOAPEnvelope envelope =
                context.getMessage().getSOAPPart().getEnvelope();
            SOAPFactory soapFactory = SOAPFactory.newInstance();
            SOAPElement wsSecHeaderElm =
                soapFactory.createElement("Security", AUTH_PREFIX, AUTH_NS);
            Name wsSecHdrMustUnderstandAttr =
                soapFactory.createName("mustUnderstand", "S",
                                       "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            wsSecHeaderElm.addAttribute(wsSecHdrMustUnderstandAttr, "1");
            SOAPElement userNameTokenElm =
                soapFactory.createElement("UsernameToken", AUTH_PREFIX,
                                          AUTH_NS);
            Name userNameTokenIdName =
                soapFactory.createName("id", "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            userNameTokenElm.addAttribute(userNameTokenIdName,
                                          "UsernameToken-ORbTEPzNsEMDfzrI9sscVA22");
            SOAPElement userNameElm =
                soapFactory.createElement("Username", AUTH_PREFIX, AUTH_NS);
            userNameElm.addTextNode("administrator");
            SOAPElement passwdElm =
                soapFactory.createElement("Password", AUTH_PREFIX, AUTH_NS);
            Name passwdTypeAttr = soapFactory.createName("Type");
            passwdElm.addAttribute(passwdTypeAttr,
                                   "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
            passwdElm.addTextNode("Passw0rd");
            userNameTokenElm.addChildElement(userNameElm);
            userNameTokenElm.addChildElement(passwdElm);
            wsSecHeaderElm.addChildElement(userNameTokenElm);
            if (envelope.getHeader() == null) {
                SOAPHeader sh = envelope.addHeader();
                sh.addChildElement(wsSecHeaderElm);
            } else {
                SOAPHeader sh = envelope.getHeader();
                sh.addChildElement(wsSecHeaderElm);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return true;
    }

In this method, we are creating the Security element in the header of the soap request and on the server side it gets asserted successfully.
If the credentials are proper, then your service will get executed else it will throw an exception saying that the username token cannot be validated.


The second way does not require any extra jars to be present in the classpath whereas in first way you will need to add some weblogic jars in classpath in order to get it working.
The problem with the second way is if you try to test it with the help of jdeveloper, you will get the following error :

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Unable to add security token for identity, token uri =http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:197)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:122)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:125)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:95)

If you analyze the stack trace carefully, you will notice that in this case jdeveloper uses classes from jars (glassfish jars) which are not part of jdk. And that's why you get the strange exception. If you run the same code from eclipse or through command line with just jdk, it will work.

Thread analysis in weblogic on linux

Thread analysis in weblogic on linux



This blog will take you through a few Linux commands to get the process id and thread id of any executing thread in a process and find the piece of code which is responsible of high usage of cpu.

This will be useful in cases where you have long running transactions and want to know which part of the code is consuming more amount of cpu.
Follow the below steps :

1. Get the pid of the java process of weblogic server running on a Linux machine :
ps -ef | grep java

Copy id of the java process

2. Get the list of all the threads belonging to the above process :
top -H -p <pid>
top commands sorts the output in descending order of cpu utilization. The first thread utilizes the higher amount of cpu.
Copy id of the first thread

3. Login to weblogic server administration console :
Go to Home > Summary of Servers > (serverName) > Monitoring > Threads > Dump Thread Stacks.

4. Search the copied tid in the thread dump.
Following stack shows thread with tid 32606 is blocked with a fat lock. This stack is generated by the weblogic socket thread and is for the explanatory purpose only :

"ExecuteThread: '0' for queue: 'weblogic.socket.Muxer'" id=24 idx=0x60 tid=32606 prio=5 alive, blocked, native_blocked, daemon
                -- Blocked trying to get lock: java/lang/String@0x86667f30[fat lock]
                at jrockit/vm/Threads.waitForUnblockSignal()V(Native Method)
                at jrockit/vm/Locks.fatLockBlockOrSpin(Locks.java:1411)[optimized]
                at jrockit/vm/Locks.lockFat(Locks.java:1512)[optimized]
                at jrockit/vm/Locks.monitorEnterSecondStageHard(Locks.java:1054)[optimized]
                at jrockit/vm/Locks.monitorEnterSecondStage(Locks.java:1005)[optimized]
                at jrockit/vm/Locks.monitorEnter(Locks.java:2179)[optimized]
                at weblogic/socket/EPollSocketMuxer.processSockets(EPollSocketMuxer.java:153)
                at weblogic/socket/SocketReaderRequest.run(SocketReaderRequest.java:29)
                at weblogic/socket/SocketReaderRequest.execute(SocketReaderRequest.java:42)
                at weblogic/kernel/ExecuteThread.execute(ExecuteThread.java:145)
                at weblogic/kernel/ExecuteThread.run(ExecuteThread.java:117)
                at jrockit/vm/RNI.c2java(JJJJJ)V(Native Method)
                -- end of trace
             
5. The stack corresponding to the tid is the piece of code where the cpu utilization is maximum.


This way you can find out the piece of code which is responsible for high cpu usage and replace it with an improved version. 

OIM 11.1.2.0.0 (11gR2) API - UserManager

OIM 11.1.2.0.0 (11gR2) API - UserManager


In this post, I will explain UserManager service API provided by Oracle Identity Manager 11.1.2.0.0 (11gR2). OIM API can be used to develop clients which can communicate with OIM to perform various operations on OIM objects.

OIM supports two ways by which clients can be developed. They are :
1.    oracle.iam.platform.OIMClient
2.    Thor.API.tcUtilityFactory

Thor.API.tcUtilityFactory API was supported in the previous versions of OIM and it is still provided in the latest releases. But oracle.iam.platform.OIMClient is recommneded by Oracle and it should be preferred over tcUtilityFactory as it provides more robust way to build clients.
Here I will give you a few code snippets which are used to connect to OIM server and perform operations on OIM objects.

  1. Setup
    • Copy <IDM_HOME>/server/client/oimclient.zip on local machine. Extract the zip file. The extracted folder contains conf, lib and oimclient.jar.
    • Add oimclient.jar and libraries from lib folder to the classpath of the client project. The project should have following jars in the classpath :
      • commons-logging.jar
      • spring.jar
      • oimclient.jar
      • jrf-api.jar
      • wlfullclient.jar
                              Generation of wlfullclient.jar is explained at this location :http://docs.oracle.com/cd/E12840_01/wls/docs103/client/jarbuilder.html
      • Make sure JDK 1.6 and ANT 1.7 are present in the classpath

    1. Initialize
      • Create OIMClient instance by preparing the environment:

      •         Hashtable<Object, Object> env = new Hashtable<Object, Object>();
                env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL, "weblogic.jndi.WLInitialContextFactory");
                env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, "t3://localhost:14000");
                System.setProperty("java.security.auth.login.config", "/home/ganesh/com.gsk.oim/config/authwl.conf");
                System.setProperty("OIM.AppServerType", "wls");
                System.setProperty("APPSERVER_TYPE", "wls");
                OIMClient oimClient = new OIMClient(env);
         
    2. Login
      • Once OIMClient is instantiated, the instance is used to login by providing correct username and password. login() method throws LoginException if login is unsuccessful:

      •         oimClient.login("xelsysadm", "Welcome1".toCharArray(), env);
               
         
    3. Lookup UserManager Service
      • UserManager is the Service class which is mainly used to perform various User operations. It can be instantiated in the following manner:

      •         UserManager userManager = oimClient.getService(UserManager.class);
    On creation of userManager instance, we have an object which can connect and perform changes in OIM server. I will discuss a few basic scenarios which are widely used by OIM clients:

    • User Creation 
    As I said earlier, UserManager is the instance which is used to perform ,as the name suggests, User specific actions. To create a User, we must pass a oracle.iam.identity.usermgmt.vo.User object to UserManager's create method. It takes UserId and a HashMap of user attributes as input. Following code snippet shows User Creation:
       
          HashMap<String, Object> userAttributeValueMap = new HashMap<String, Object>();
            userAttributeValueMap.put("act_key", new Long(1));
            userAttributeValueMap.put("User Login", userId);
            userAttributeValueMap.put("First Name", "Ganesh");
            userAttributeValueMap.put("Last Name", "Kamble");
            userAttributeValueMap.put("Email", "ganesh.kamble@abc.com");
            userAttributeValueMap.put("usr_password", "P1ssword");
            userAttributeValueMap.put("Role", "OTHER");
            User user = new User("Ganesh", userAttributeValueMap);
            userManager.create(user);

       
        Here we have created a userAttributeValueMap which stores mandatory attributes required for User Creation through OIM API. User object is created using an Unique Id and the HashMap. We pass this User object to UserManager.create(user) method. It returns UserManagerResult. We can verify the status by using UserManagerResult.getStatus() method. 

    • User Retrieval
        To retrieve the details of a user, UserManager provides several methods named getDetails() distinguished by the input parameters. I will take a method which takes input as userid, a set of attributes which are to be returned for each user and a boolean flag specifying whether the userid is the user login. If blank Set is given in the input, the method returns all the attributes of the User.

            Set<String> resAttrs = new HashSet<String>();
            User user = userManager.getDetails("Ganesh", resAttrs, true); 


    • User Update
         UserManager provides methods named modify to update User details in OIM. I will talk about the method which takes User Object as input. In the following code snippet, I have retrieved a User with the loginId "Ganesh" and updated it with the changed user attributes
       
           Set<String> resAttrs = new HashSet<String>();
            User retrievedUser = userManager.getDetails("Ganesh", resAttrs, true);

            HashMap<String, Object> userAttributeValueMap = new HashMap<String, Object>();
            userAttributeValueMap.put("act_key", new Long(1));
            userAttributeValueMap.put("User Login", userId);
            userAttributeValueMap.put("First Name", "Ganesh");
            userAttributeValueMap.put("Last Name", "Kamble");
            userAttributeValueMap.put("Email", "ganesh.kamble@xyz.com");
            userAttributeValueMap.put("usr_password", "P@ssword");
            userAttributeValueMap.put("Role", "Other");

            User user = new User((String) retrievedUser.getAttribute("User Login"), userAttributeValueMap);
            userManager.modify(user); 


    • User Search
    OIM provides the support to search Users based on a particular criteria. We build a SearchCriteria based on which the Users need to be inquired, pass the SearchCriteria instance to UserManager.search() method as shown below:
       
           SearchCriteria searchCriteria = new SearchCriteria("Email", "ganesh.kamble@xyz.com", SearchCriteria.Operator.EQUAL);
            Set<String> attrNames = null;
            HashMap<String, Object> mapParams = new HashMap<String, Object>();
            mapParams.put("STARTROW", 0);
            mapParams.put("ENDROW", 1);
            List<User> users = null;
            users = userManager.search(searchCriteria, attrNames, mapParams);

       
         Here I have prepared a SearchCriteria which indicates the Email of the User should be EQUAL to ganesh.kamble@xyz.com. mapParams are the ConfigurationParameters which provides the functionality of more granular search. They can be STARTROW, ENDROW, SORTEDBY and SORTORDER. Here I have used STARTROW and ENDROW which indicates which subset of the complete result should be fetched. SORTEDBY sorts the result by User Login by default. It can be changed to the desired attribute. SORTEDORDER can be SortOrder.DESCENDING or SortOrder.ASCENDING latter being the default.

    • Lock/Unlock User Account
    The following methods locks/unlocks a particular user account.
                     userManager.lock(userId, true, true);

                        Here first parameter is the id of the user to be locked. Second parameter indicates whether its a manual lock (true) or system lock (false). And third parameter indicates whether the userId is the UserLogin Id.

                    userManager.unlock(userId, true);

                        Here first parameter is the id of the user to be locked. Second parameter is true if the userId is the UserLogin id.



        In this post, I have tried to cover some basic user operations on User entity. Each of the above operation comes in different flavours. You can find the entire set of OIM API at location : http://docs.oracle.com/cd/E27559_01/apirefs.1112/e28159/toc.htm . The detailed information on how to use the API is explained at this location : http://docs.oracle.com/cd/E27559_01/dev.1112/e27150/apis.htm#BCFGCGHI .

        The set of attributes which OIM understands is given below. These attributes can be passed in the HashMap as an input. Also when you inquire the user, these attributes will be returned.

        [ FA Territory, Employee Number, Middle Name, Manually Locked, usr_disabled, Display Name, LDAP Organization, usr_locked, Currency, Time Format, usr_created, usr_deprovisioning_date, Full Name, Country, Accessibility Mode, usr_pwd_expire_date, usr_pwd_cant_change, Email, usr_data_level, Automatically Delete On, Locked On, usr_login_attempts_ctr, Last Name, First Name, Locality Name, usr_policy_update, Street, Embedded Help, Department Number, usr_createby, usr_pwd_warned, Manager Login, Telephone Number, Manager First Name, usr_updateby, Home Phone, LDAP Organization Unit, usr_pwd_min_age_date, User Login, Title, Role, FA Language, Password Generated, usr_provisioning_date, usr_pwd_warn_date, Organization Name, usr_locale, usr_update, Date Format, usr_timezone, Mobile, usr_pwd_reset_attempts_ctr, End Date, Pager, usr_deprovisioned_date, Color Contrast, PO Box, usr_create, LDAP GUID, Xellerate Type, usr_change_pwd_at_next_logon, usr_provisioned_date, Common Name, Start Date, usr_manager_key, Number Format, usr_pwd_expired, Hire Date, User Name Preferred Language, Home Postal Address, Font Size, Manager Last Name, Description, Fax, Postal Code, act_key, usr_key, Common Name Generated, Status, Generation Qualifier, Postal Address, State, Manager Display Name, usr_pwd_never_expires, Initials, usr_pwd_must_change, LDAP DN ]