25.2 Security

This section describes the security model used for the REST services.

The security model attempts to satisfy these objectives:

25.2.1 Architecture

The security model supports two options for making requests. The first one (Option 1) consists of passing in the user credentials in an HTTP header (default: RESTAuthorization). The second approach (Option 2) consists of a two request approach. In the second option, an authorization request is required first and all subsequent requests pass in the session secret token in an HTTP header. The header defaults to RESTSessionSecret.

Both options require the passing of sensitive data on the wire. Therefore, Novell highly recommends that you run this application in a TLS/SSL environment (HTTPS). Otherwise the user credentials could be exposed to a man-in-the-middle attack.

Either approach will work. However, Novell recommends using Option 2 (the Session Secret Security Model approach) rather than Option 1 (the Authorization Security Model approach). Option 2 offers more protection against discovering the actual user credentials. The credentials are maintained by the RIS server and are discovered using a unique access token through the RESTSessionSecret HTTP header.

Option 1: Authorization Security Model

This model is the same as the Basic authorization model. This model is recommended for developers who do not use JavaScript for their client application.

Here is the flow of control used with this option:

  1. Developers must include the Base64(username:password)) string in an HTTP header (RESTAuthorization) before making the call to the REST service. The HTTP header name can be configured at installation time. The default name is:

    RESTAuthorization
    
  2. The client application sends the request to the RIS server.

  3. The RIS server extracts the credentials from the header and passes those credentials onto the SOAP service. The actual authentication check is performed at the User Application server.

  4. The User Application SOAP call is either granted or denied and the result is returned to the RIS server.

  5. The RIS server returns the result to the client application.

The following picture illustrates the flow:

Figure 25-1 Option 1 Authorization Flow

Example 25-1 Example

Suppose you issue the following REST call:

/v1/wf/definitions

Here is the request:

GET /RIS/v1/wf/definitions HTTP/1.1 
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009022800 SUSE/3.0.7-1.4 Firefox/3.0.7 
Accept: application/json 
Accept-Language: en,it;q=0.8,fr;q=0.6,de;q=0.4,en-us;q=0.2 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 
RESTAuthorization: YWRtaW4tcHJvdjp0ZXN0 

Here is the response:

HTTP/1.1 200 OK 
Server: Apache-Coyote/1.1 
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1 
Content-Type: application/json 
Transfer-Encoding: chunked 
Date: Tue, 31 Mar 2009 13:48:05 GMT 

7d2 
[
   {
      "Links": [
         {
            "Link": "/RIS/v1/wf/processes?filter=Definition=cn=Change+Title+Single+Approval,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
            "Type": "wf/processes",
            "Value": "Workflow Processes"
         },
         {
            "Link": "/RIS/v1/wf/workitems?filter=Definition=cn=Change+Title+Single+Approval,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
            "Type": "wf/workitems",
            "Value": "Workflow Workitems"
         }
      ],
      "DataItems": [],
      "DN": "cn=Change Title Single Approval,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
      "GUID": "5a4f7af2142189430d935a4f7af21421",
      "Link": "/RIS/v1/wf/definitions/5a4f7af2142189430d935a4f7af21421",
      "Value": "Change Title Single Approval",
      "Category": "accounts",
      "DigitalSignatureType": "not-required",
      "Description": "Change Title",
      "Operation": "0",
      "Recipient": ""
   },
   {
      "Links": [
         {
            "Link": "/RIS/v1/wf/processes?filter=Definition=cn=Change+Title,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
            "Type": "wf/processes",
            "Value": "Workflow Processes"
         },
         {
            "Link": "/RIS/v1/wf/workitems?filter=Definition=cn=Change+Title,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
            "Type": "wf/workitems",
            "Value": "Workflow Workitems"
         }
      ],
      "DataItems": [],
      "DN": "cn=Change Title,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
      "GUID": "71e22c1cf4b4e74fbdb871e22c1cf4b4",
      "Link": "/RIS/v1/wf/definitions/71e22c1cf4b4e74fbdb871e22c1cf4b4",
      "Value": "Change Title",
      "Category": "accounts",
      "DigitalSignatureType": "not-required",
      "Description": "Change Title",
      "Operation": "0",
      "Recipient": ""
   }
]

Option 2: Session Secret Security Model

The session secret security model allows a developer to ask for an authorization unique id. This session secret ID is then used on all subsequent calls. This is to allow client developers to be more secured than passing user credentials for every call.

Here is the flow of control used with this option:

  1. Developers must first make a call to the /v1/AuthorizationSession REST service to obtain a session token. This is a POST call with the credentials (Base64(username:password)) in the content of the message in a JSON object (see section 4).

  2. The RIS server will then create a session object and stores the credentials in memory for the duration of the session. The session secret token is returned to the client application via a JSON object.

  3. Developers must include the Session Secret token string in an HTTP header (RESTSessionSecret) before making any subsequent REST service calls. The HTTP header name can be configured at installation time. The default name is:

    RESTSessionSecret
    
  4. The client application sends the request to the RIS server.

  5. The RIS server extracts the session secret token from the HTTP header and retrieves the credentials from memory based on the token for that session. The credentials are passed onto he SOAP service. The actual authentication check is performed at the User Application server.

  6. The User Application SOAP call is either granted or denied and the result is returned to the RIS server.

  7. The RIS server returns the result to the client application.

The following picture illustrates the flow:

Figure 25-2 Option 2 Authorization Flow

Example 25-2 Example

First, you issue the following call to the Authorization REST Service:

/v1/AuthorizationSession

Here is the request:

POST /RIS/v1/AuthorizationSession HTTP/1.1 
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009022800 SUSE/3.0.7-1.4 Firefox/3.0.7 
Accept: application/json 
Accept-Language: en,it;q=0.8,fr;q=0.6,de;q=0.4,en-us;q=0.2 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 
Content-Type: application/json; charset=UTF-8 
Content-Length: 47 
Pragma: no-cache 
Cache-Control: no-cache 

{
   "Authorization" : "YWRtaW4tcHJvdjp0ZXN0"
}

Here is the response:

HTTP/1.1 200 OK 
Server: Apache-Coyote/1.1 
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1 
Set-Cookie: JSESSIONID=17B5528DEEC66610D0FBB456992E10ED; Path=/RIS 
Content-Type: application/json 
Transfer-Encoding: chunked 
Date: Tue, 31 Mar 2009 13:54:26 GMT 

35 
{"SessionSecret": "17B5528DEEC66610D0FBB456992E10ED"} 

Next, you issue the REST call:

/v1/wf/definitions

Here is the request:

GET /RIS/v1/wf/definitions HTTP/1.1 
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009022800 SUSE/3.0.7-1.4 Firefox/3.0.7 
Accept: application/json 
Accept-Language: en,it;q=0.8,fr;q=0.6,de;q=0.4,en-us;q=0.2 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 
RESTSessionSecret:  17B5528DEEC66610D0FBB456992E10ED

Here is the response:

HTTP/1.1 200 OK 
Server: Apache-Coyote/1.1 
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1 
Content-Type: application/json 
Transfer-Encoding: chunked 
Date: Tue, 31 Mar 2009 13:48:05 GMT 
 
7d2 
[
   {
      "Links": [
         {
            "Link": "/RIS/v1/wf/processes?filter=Definition=cn=Change+Title+Single+Approval,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
            "Type": "wf/processes",
            "Value": "Workflow Processes"
         },
         {
            "Link": "/RIS/v1/wf/workitems?filter=Definition=cn=Change+Title+Single+Approval,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
            "Type": "wf/workitems",
            "Value": "Workflow Workitems"
         }
      ],
      "DataItems": [],
      "DN": "cn=Change Title Single Approval,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
      "GUID": "5a4f7af2142189430d935a4f7af21421",
      "Link": "/RIS/v1/wf/definitions/5a4f7af2142189430d935a4f7af21421",
      "Value": "Change Title Single Approval",
      "Category": "accounts",
      "DigitalSignatureType": "not-required",
      "Description": "Change Title",
      "Operation": "0",
      "Recipient": ""
   },
   {
      "Links": [
         {
            "Link": "/RIS/v1/wf/processes?filter=Definition=cn=Change+Title,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
            "Type": "wf/processes",
            "Value": "Workflow Processes"
         },
         {
            "Link": "/RIS/v1/wf/workitems?filter=Definition=cn=Change+Title,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
            "Type": "wf/workitems",
            "Value": "Workflow Workitems"
         }
      ],
      "DataItems": [],
      "DN": "cn=Change Title,cn=RequestDefs,cn=AppConfig,cn=PicassoDriver,cn=TestDrivers,o=novell",
      "GUID": "71e22c1cf4b4e74fbdb871e22c1cf4b4",
      "Link": "/RIS/v1/wf/definitions/71e22c1cf4b4e74fbdb871e22c1cf4b4",
      "Value": "Change Title",
      "Category": "accounts",
      "DigitalSignatureType": "not-required",
      "Description": "Change Title",
      "Operation": "0",
      "Recipient": ""
   }
]

25.2.2 Authorization REST Service

The Authorization REST Service lets you obtain a session token. When you make a call to the service, the RIS server creates a session object and stores the credentials in memory for the duration of the session. The session secret token is returned to the client application via a JSON object. The only media type supported is application/json, which uses a JSON Array format for the list of items and a single JSON object for detailed information.

The following table shows the complete URI syntax for all resource end points associated with the Authorization REST Service, along with a description for each URI and a list of supported HTTP methods:

Table 25-1 URI Syntax for the Authorization REST Service

URI

Description

/v1/AuthorizationSession

Creates a new session authorization session and obtains a session token. The following HTTP methods are supported:

GET – Not supported

POST – Creates a new authorization session object and returns the session secret token in the response.

Request JSON Object:

{ "Authorization" : Base64(username:password)}

Response JSON Object:

{ "SessionSecret": "session secret token”}

PUT – Not supported

DELETE – Not supported

/v1/AuthorizationSession/{session secret token}

Deletes and invalidates the authorization session object. The following HTTP methods are supported:

GET – Not supported

PUT – Not supported

POST – Not supported

DELETE – Deletes and invalidates the authorization session object.

POST with Matrix parameter DELETE – Same as DELETE because of limitations in browsers to set the DELETE method

The following matrix parameters are available for debugging and displaying the schema:

Table 25-2 Matrix Parameters for Debugging and Displaying the Schema

URI

Description

/v1/AuthorizationSession;debug

This debug matrix parameter displays the workitems JSON structure in human readable format, as opposed to compressed format. This matrix parameter can be put anywhere in the URI.

/v1/AuthorizationSession;schema

The schema matrix parameter can be put anywhere in the URI and in combination with the “Accept” header type will return the appropriate schema document for the content type. In this case a JSON schema document is returned for the workitems.

Example 25-3 Example

Here is an example of a call to the Authorization service that includes the debug and schema parameters:

/v1/AuthorizationSession;debug;schema

Here is the request:

POST /RIS/v1/AuthorizationSession;schema;debug HTTP/1.1 
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009022800 SUSE/3.0.7-1.4 Firefox/3.0.7 
Accept: application/json 
Accept-Language: en,it;q=0.8,fr;q=0.6,de;q=0.4,en-us;q=0.2 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 
Content-Type: application/json; charset=UTF-8 
Content-Length: 38 
Pragma: no-cache 
Cache-Control: no-cache 

{
   "Authorization" : "YWRtaW4tcHJvdjp0ZXN0"
}

Here is the response:

HTTP/1.1 200 OK 
Server: Apache-Coyote/1.1 
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1 
Content-Type: application/json 
Transfer-Encoding: chunked 
Date: Tue, 31 Mar 2009 13:18:45 GMT 

171 
{
   "Request": {"SessionInfo": {
      "description": "schema for: /v1/AuthorizationSession",
      "type": "object",
      "properties": {"Authorization": {"type": "string"}}
   }},
   "Response": {"SessionSecret": {
      "description": "schema for: /v1/AuthorizationSession",
      "type": "object",
      "properties": {"SessionSecret": {"type": "string"}}
   }}
} 

25.2.3 Configuration Parameters

The RIS.war uses the following filter parameters, all of which are set in the WEB.XML file.

Table 25-3 Filter Parameters

Parameter

Description

AUTHORIZATION_HEADER

The AUTHORIZATION_HEADER filter parameter specifies the HTTP header name for option 1 - Authorization Security model. If not supplied, then the default will be:

RESTAuthorization

This HTTP header will hold the user credentials.

Example:

RESTAuthorization: Base64(username:password)

SESSION_SECRET_HEADER

The SESSION_SECRET_HEADER filter parameter specifies the HTTP header name to hold the session secret for Option 2 – Session Secret Security Model. If not supplied, then the default will be:

RESTSessionSecret

This HTTP header will hold the session secret returned from the RIS server when an access token is requested via the REST service:

/RIS/v1/AuthenticationSession

Example:

RESTSessionSecret: <token>

USER_APP_URL

The USER_APP_URL filter parameter will point to the User Application associated with the RIS server. All SOAP calls will use this URL for the SOAP end point.

STUB_CONNECTION_POOL

The STUB_CONNECTION_POOL filter parameter holds the number of connection that we want to maintain from the RIS server to the User Application server. This is to make the client perform better.

In addition to these filter parameters, the configuration also supports the following session parameter:

Table 25-4 Session Parameter

Parameter

Description

Session Timeout

This setting is used to control the length of the sessions. It is specified in minutes.

Here is a sample Web.XML that illustrates the use of the configuration parameters:

<filter>
        <filter-name>Authorization Filter</filter-name>
        <filter-class>com.novell.ris.common.impl.ServletFilter</filter-class>
        <init-param>
            <param-name>AUTHORIZATION_HEADER</param-name>
            <param-value>RESTAuthorization</param-value>
        </init-param>    
        <init-param>
            <param-name>SESSION_SECRET_HEADER</param-name>
            <param-value>RESTSessionSecret</param-value>
        </init-param>    
        <init-param>
            <param-name>USER_APP_URL</param-name>
            <param-value>http://localhost:8080/IDMProv</param-value>
        </init-param>
<!-- If not entered, Stub Connection size will default to 10 stub connections -->
        <init-param>
            <param-name>STUB_CONNECTION_POOL</param-name>
            <param-value>10</param-value>
        </init-param>    
    </filter>
….
    <session-config>
      <session-timeout>30</session-timeout> 
    </session-config>