Thursday Jul 12, 2012

Adding RESTful Web Services to Oracle Identity Manager 11g

Overview

Organization's are leveraging RESTful Web Services to integrate multiple client interfaces and devices with Internet-centric data services. We will cover how RESTful Web Services can be added to Oracle Identity Manager (OIM) 11g using the Jersey (JAX-RS) framework and Project OpenPTK.

RESTful Web Services

RESTful Web Services have become a "defacto" Application Programming Interface (API) for the Internet. A typical RESTful Web Service architecture leverages HTTP to implement basic Create, Read, Update and Delete (CRUD) operations. The following table shows how RESTful Web Services use the combination of HTTP Operations and URIs to support these CRUD operations.

Resource - URI
CRUD HTTP
Operation
Collection
http://acme.com/users
Element
http://acme.com/users/abc123
Create POST Create an entry in the collection. Entry's Id is usually assigned and returned Treat the member as a Collection, Create a sub-collection
Read GET List the collection members Retrieve a representation of the member. Using the MIME-type
Update PUT Replace the entire collection with another collection Update the member of the collection. Maybe create if it does not exist
Delete DELETE Delete the entire collection Delete the member of the collection

RESTful Web Services enable the developer to create user interfaces using their choice of design tools and frameworks. RESTful Web Services can be consumed by a traditional Browser interface (leveraging AJAX-type techniques) as well as by mobile and tablet devices leveraging platform specific RESTful client frameworks.

Oracle Identity Manager 11g and Jersey (JAX-RS)

The Oracle Identity Manager (OIM) 11g provides a powerful Java API that can be used to programmatically manage user identities. Here's a blog entry detailing the use of the OIM 11g Java APIs.

RESTful Web Services are easy to create using the Jersey framework. The Jersey framework implements the JAX-RS specification and works with most Java development tools and Java Servlet Containers. Jersey provides a set of Java Annotations to provide RESTful Web Services. The following table highlights some of the Jersey Annotations:

Annotation Description
@Path("/users") Name of a relative URI path
@POST Designates method for HTTP POST Operation (Create)
@GET Designates method for HTTP GET Operation (Read)
@PUT Designates method for HTTP PUT Operation (Update)
@DELETE Designates method for HTTP DELETE Operation (Delete)
@Produces("text/plain") Specify the MIME-types to send back to the client
@Consumes("application/json") Specify the MIME-types, the resource can consume, sent by the client

Project OpenPTK

Project OpenPTK is an open source provisioning toolkit that extends the capabilities of a provisioning solution. Project OpenPTK leverges the Jersey framework to expose RESTful Web Services and it can leverage Oracle Identity Manager (OIM) 11g using its Java APIs. Project OpenPTK supports both JSON and XML RESTful Web Service data payloads, to and from the Client.

restful openptk oim11g overview

Configuration

The RESTful Web Service demonstration environment was configured using Project OpenPTK (v2.1) deployed to the same Weblogic domain that is hosting Oracle Identity Manager (OIM) 11g. Project OpenPTK has a set of documentation which covers configuration / installation procedures in more detail.

Prerequisites

Project OpenPTK is available from a Subversion (svn) on-line source code control system at http://java.net/projects/openptk. You will need svn to download the project. The download page contains more information on how to access the source code. Create a new directory to store the project's source code.

mkdir $HOME/source
cd $HOME/source
svn checkout \
https://svn.java.net/svn/openptk~svn/tags/release-2.1/openptk \
openptk --username guest

Project OpenPTK uses Maven (mvn) for building the source code and obtaining dependent JAR files. The Setup using Maven document provides more details on how to use maven. Run the mvn install command to download the core dependency files.

Procedure

Project OpenPTK uses Service modules to interface with identity repositories. A Service module was create using the Oracle Identity Manager (OIM) 11g OIMClient Java API. The following steps highlight how to integrate, build, and deploy Project OpenPTK to support Oracle Identity Manager 11g.

  1. Obtain the Oracle Identity Manager 11g oimclient.jar file.
  2. Install the oimclient.jar file into a local maven repository
  3. Build the OpenPTK Server using the oim11g Service module
  4. Copy the generated war file to the Weblogic server where Oracle Identity Manager 11g is installed
  5. Expand the war file:
    1. Update the openptk.xml configuration file
    2. Include the oimclient.jar file
  6. Deploy the OpenPTK Server to Weblogic

See the OpenPTK Service for OIM11g on Weblogic documentation page for detailed installation procedures.


Demonstration

Log into the OpenPTK Admin Interface and confirm that the Oracle Identity Manager 11g Context is working correctly. After logging in (http://localhost:7001/openptk-server):

  • Select the Contexts menu
  • Select the User-Oracle-OIMClient uri.
  • To list the Users, select the uri for the subjects
openptk admin interface

The curl command-line utility will be used to demonstrate the RESTful Web Services.

Authenticate

Project OpenPTK has an authentication mechanism. When the user is authenticated a Session is created within the OpenPTK Server and a HTTP Cookie is created for the user. Normally the web-browser would manage the HTTP Cookie. Since curl is being used, the Cookie returned from the authentication process will be saved in a text file called cookies.txt. The Cookie text file will be used on all the other curl commands.

Command:
curl -c cookies.txt \
-H "Accept: text/plain" \
http://oim11g:7001/openptk-server/login\?user=openptkconfig\&password=password\&clientid=identitycentral
Output:
<html>
<head>
<title>Servlet Login</title>
</head>
<body>
<h1>Login Success!</h1>
</body>
</html>

The contents of the cookies.txt file:

# Netscape HTTP Cookie File
# http://www.netscape.com/newsref/std/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.

oim11g FALSE / FALSE 0 JSESSIONID       Ht8JP8zS3yyhWh5XrD42Lb6rP1r7HF5LnR09vDGQkH7QmkKb8Gfh!697966766
oim11g FALSE / FALSE 0 OPENPTKSESSIONID 6be67d1e-ea37-4b45-bbaf-d34f270940b9

Search

Search for existing OIM11g users that have a firstname or lastname that contains "Jack". The OpenPTK Server supports encoding the response data in a number of different formats. To specify what encoding type to use, set the Accept HTTP Header variable to one of these MIME-type values:

  • application/json
  • application/xml
  • text/plain
  • text/html

We use the HTTP GET method (on the User-Oracle-OIMClient/subjects collection) to search for the users. The HTTP query parameter search is used to specify the search string.

Command:
curl -X GET \
-b cookies.txt \
-H "Accept: application/json" \
http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/?search=Jack
Output:
{
    "response" : {
        "uri" : "http:\/\/oim11g:7001\/openptk-server\/resources\/contexts\/User-Oracle-OIMClient\/subjects\/",
        "state" : "SUCCESS",
        "length" : 2,
        "offset" : 0,
        "quantity" : 2,
        "results" : [
            {
                "subject" : {
                    "uri" : "http:\/\/oim11g:7001\/openptk-server\/resources\/contexts\/User-Oracle-OIMClient\/subjects\/JHARKNESS",
                    "uniqueid" : "JHARKNESS",
                    "attributes" : {
                        "uniqueid" : "JHARKNESS",
                        "email" : "jack@torchwood.org",
                        "roles" : "Full-Time",
                        "lastname" : "Harkness",
                        "firstname" : "Jack",
                        "lastcommafirst" : "Harkness, Jack"
                    }
                }
            },
            {
                "subject" : {
                    "uri" : "http:\/\/oim11g:7001\/openptk-server\/resources\/contexts\/User-Oracle-OIMClient\/subjects\/JSPARROW",
                    "uniqueid" : "JSPARROW",
                    "attributes" : {
                        "uniqueid" : "JSPARROW",
                        "email" : "jack@blackpearl.org",
                        "roles" : "Full-Time",
                        "lastname" : "Sparrow",
                        "firstname" : "Jack",
                        "lastcommafirst" : "Sparrow, Jack"
                    }
                }
            }
        ]
    }
}
Results: oim admin ui search

Create

We use the HTTP POST method (on the User-Oracle-OIMClient/subjects collection) to create a new user, in the collection. The curl -v option is used to show data being passed in and to show the Location value that is returned with the full URI of the created element (subject). Because we are sending in data that is "json" encoded, the HTTP Header variable Content-Type needs to be set to the application/json MIME-type. The successful operation returns a HTTP response code of 201 Created

Command:
curl -X POST -v \
-b cookies.txt \
-H "Content-Type: application/json" \
-d '{"subject" : { "attributes" : { "lastname" : "Bauer", "firstname" : "Jack" }}}' \
http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects
Output:
* About to connect() to oim11g port 7001
*   Trying 127.0.0.1... connected
* Connected to oim11g (127.0.0.1) port 7001
< POST /openptk-server/resources/contexts/User-Oracle-OIMClient/subjects HTTP/1.1
< User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
< Host: oim11g:7001
< Accept: */*
< Cookie: OPENPTKSESSIONID=6be67d1e-ea37-4b45-bbaf-d34f270940b9
< Content-Type: application/json
< Content-Length: 78
< 
< {"subject" : { "attributes" : { "lastname" : "Bauer", "firstname" : "Jack" }}}
HTTP/1.1 201 Created
> Cache-Control: no-cache, no-transform
> Date: Wed, 11 Jul 2012 04:38:59 GMT
> Location: http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1
> Content-Length: 0
> Content-Type: application/json
> X-ORACLE-DMS-ECID: 0000JXoLJqJFw000jzwkno1FzDlJ00001r
> X-Powered-By: Servlet/2.5 JSP/2.1
* Connection #0 to host oim11g left intact
* Closing connection #0
Results:

Read

We use the HTTP GET method (on the User-Oracle-OIMClient/subjects/jbauer1 element) to read the user. We can retrieve the data using a number of different encoding formats: json, xml, plain, html. The examples below demonstrate how the HTTP Header variable Accept is used to "tell" the server what MIME-type we (the client) want to "accept".

Command:
curl -X GET \
-b cookies.txt \
-H "Accept: application/json" \
http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1

curl -X GET \
-b cookies.txt \
-H "Accept: application/xml" \
http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1

curl -X GET \
-b cookies.txt \
-H "Accept: text/plain" \
http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1
Output:
{
    "response" : {
        "uri" : "http:\/\/oim11g:7001\/openptk-server\/resources\/contexts\/User-Oracle-OIMClient\/subjects\/jbauer1",
        "state" : "SUCCESS",
        "status" : "Entry found",
        "subject" : {
            "uniqueid" : "JBAUER1",
            "attributes" : {
                "manager" : null,
                "status" : "Active",
                "lastname" : "Bauer",
                "firstname" : "Jack",
                "type" : "End-User",
                "uniqueid" : "JBAUER1",
                "title" : null,
                "email" : "Jack.Bauer@openptk.org",
                "roles" : "Full-Time",
                "forgottenPasswordQuestions" : [
                   "What is your favorite color?",
                   "What is your mother's maiden name?",
                   "What is the city of your birth?"],
                "telephone" : null,
                "fullname" : "Jack Bauer",
                "lastcommafirst" : "Bauer, Jack"
            }
        }
    }
}
Output:
<?xml version="1.0" encoding="UTF-8"?>
<response>
   <uri type="string">http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1</uri>
   <state type="string">SUCCESS</state>
   <status type="string">Entry found</status>
   <subject>
      <uniqueid type="string">JBAUER1</uniqueid>
      <attributes>
         <manager type="string"></manager>
         <status type="string">Active</status>
         <lastname type="string">Bauer</lastname>
         <firstname type="string">Jack</firstname>
         <type type="string">End-User</type>
         <uniqueid type="string">JBAUER1</uniqueid>
         <title type="string"></title>
         <email type="string">Jack.Bauer@openptk.org</email>
         <roles type="string">Full-Time</roles>
         <forgottenPasswordQuestions type="string">
            <values>
               <value>What is your favorite color?</value>
               <value>What is your mother's maiden name?</value>
               <value>What is the city of your birth?</value>
            </values>
         </forgottenPasswordQuestions>
         <telephone type="string"></telephone>
         <fullname type="string">Jack Bauer</fullname>
         <lastcommafirst type="string">Bauer, Jack</lastcommafirst>
      </attributes>
   </subject>
</response>
Output:
response=
    uri="http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1"
    state="SUCCESS"
    status="Entry found"
    subject=
        uniqueid="JBAUER1"
        attributes=
            manager=
            status="Active"
            lastname="Bauer"
            firstname="Jack"
            type="End-User"
            uniqueid="JBAUER1"
            title=
            email="Jack.Bauer@openptk.org"
            roles="Full-Time"
            forgottenPasswordQuestions=
               "What is your favorite color?"; 
               "What is your mother's maiden name?"; 
               "What is the city of your birth?"
            telephone=
            fullname="Jack Bauer"
            lastcommafirst="Bauer, Jack"

Update

We use the HTTP PUT method (on the User-Oracle-OIMClient/subjects/jbauer1 element) to update an existing user, in the collection. The curl -v option is used to show data being passed in and to show the details of the update operation. Because we are sending in data that is "json" encoded, the HTTP Header variable Content-Type needs to be set to the application/json MIME-type. The successful operation returns a HTTP response code of 204 No Content

Command:
curl -X PUT \
-v -b cookies.txt \
-H "Content-Type: application/json" \
-d '{ "subject" : { "attributes" : { "title" : "Special Agent", "email" : "jack@ctu.org" } } }' \
http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1
Output:
* About to connect() to oim11g port 7001
*   Trying 127.0.0.1... connected
* Connected to oim11g (127.0.0.1) port 7001
> PUT /openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1 HTTP/1.1
> User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: oim11g:7001
> Accept: */*
> Cookie: OPENPTKSESSIONID=486104f5-0cdb-4b49-8a67-1b1929629538
> Content-Type: application/json
> Content-Length: 90
> 
> { "subject" : { "attributes" : { "title" : "Special Agent", "email" : "jack@ctu.org" } } }
HTTP/1.1 204 No Content
< Cache-Control: no-cache, no-transform
< Date: Thu, 12 Jul 2012 03:00:03 GMT
< Content-Length: 0
< Content-Type: application/json
< X-ORACLE-DMS-ECID: 0000JXt8GHAFw000jzwkno1FzDlJ000020
< X-Powered-By: Servlet/2.5 JSP/2.1
* Connection #0 to host oim11g left intact
* Closing connection #0
Results:

Delete

We use the HTTP DELETE method (on the User-Oracle-OIMClient/subjects/jbauer1 element) to delete the user, in the collection. The curl -v option is used to show data being passed in and to show the details of the delete operation. The successful operation returns a HTTP response code of 204 No Content

Command:
curl -X DELETE \
-v -b cookies.txt \
http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1
Output:
* About to connect() to oim11g port 7001
*   Trying 127.0.0.1... connected
* Connected to oim11g (127.0.0.1) port 7001
> DELETE /openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1 HTTP/1.1
> User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: oim11g:7001
> Accept: */*
> Cookie: OPENPTKSESSIONID=6789055b-2561-489e-a6bd-3c5424859f81
> 
< HTTP/1.1 204 No Content
< Cache-Control: no-cache, no-transform
< Connection: close
< Date: Thu, 12 Jul 2012 03:44:49 GMT
< Content-Length: 0
< Content-Type: text/plain
< X-ORACLE-DMS-ECID: 0000JXtIW4EFw000jzwkno1FzDlJ00002A
< X-Powered-By: Servlet/2.5 JSP/2.1
* Closing connection #0
Results:
curl -X GET \
-v -b cookies.txt \
-H "Accept: text/plain" \
http://oim11g:7001/openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1

* About to connect() to oim11g port 7001
*   Trying 127.0.0.1... connected
* Connected to oim11g (127.0.0.1) port 7001
> GET /openptk-server/resources/contexts/User-Oracle-OIMClient/subjects/jbauer1 HTTP/1.1
> User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: oim11g:7001
> Cookie: OPENPTKSESSIONID=6789055b-2561-489e-a6bd-3c5424859f81
> Accept: text/plain
> 
< HTTP/1.1 404 Not Found
< Cache-Control: no-cache, no-transform
< Date: Thu, 12 Jul 2012 03:49:38 GMT
< Content-Length: 9
< Content-Type: text/html; charset=UTF-8
< X-ORACLE-DMS-ECID: 0000JXtJak1Fw000jzwkno1FzDlJ00002C
< X-Powered-By: Servlet/2.5 JSP/2.1
Connection #0 to host oim11g left intact
* Closing connection #0

Even more ...

We have covered how to use Jersey (JAX-RS), via Project OpenPTK, to implement RESTful Web Services for Oracle Identity Manager 11g. We focused on basic Create, Read, Update, Delete and Search operations related to Users. The OpenPTK project also includes RESTful Web Service examples for other tasks such as Self-Service Registration which leverages the Oracle Identity Manager 11g registration feature. Take a look at the CAPTCHA and Identity Manager blog entry that uses the registration feature.

YouTube Video

About

Scott Fehrman

Search

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

No bookmarks in folder

Projects

No bookmarks in folder

Ref. Material

No bookmarks in folder