ISAM for Web and Mobile – OAuth Authentication and Sessions

 

[14 July, 2016] There has been a few updates to this article related to the ISAM 9.0.1 release, adding some enhancements for OAuth. This includes enhancements to the session lifetime, and session logout, also some technical updates regarding the use of DSC.

ISAM has made it’s forth release of the year, with version 8.0.0.4 released at the end of June.

A list of new features has been assembled here in the knowledge center.

In this post, I want to talk more about this feature:

  • OAuth authentication

WebSEAL can now create an authenticated session by using an OAuth token. See the documentation for the EAS here: Support for OAuth authorization decisions.

In particular about some of the capabilities this introduces to the WebSEAL environment for Native mobile applications.

Historical OAuth capabilities

In versions of ISAM prior to v8.0.0.4, OAuth passing through WebSEAL was validated via an EAS. This meant that all the authorization is handled by ISAM for Mobile (or TFIM in older deployments) and WebSEAL passed the request to the junctioned servers as an ‘unauthenticated’ but ‘authorized’ request. This created some interesting challenges around audit logging and didn’t allow for any authorization to be handled by WebSEAL based on ACLs or context based access using attributes that are related to the OAuth token set.

OAuth Authentication to WebSEAL

In 8.0.0.4, a new stanza has been introduced to the WebSEAL configuration file [oauth].

From version 9.0.1, the auto_config script will configure most of these settings (including OAuth-Auth Sessions, and session logout) by default

Authentication
Figure 1. OAuth Authentication

Note: If you have upgraded from an earlier version, you may not have all the options and descriptive text available so I’ve reproduced it below.

[oauth]

# Enable authentication using Open Authorization (OAuth) mechanism.
# One of <http, https, both, none>
#
# The OAuth authentication mechanism should be considered only as part of a
# Mobile scenario, where a session can be established based on the Bearer
# token in the Authorization Header.
oauth-auth = https

# The Provider ID of the default OAuth federation at TFIM. If a Provider ID
# is not provided in the request using the fed-id-param option, this provider
# ID will be used for OAuth requests. The Provider ID of a federation can be
# found on the federation properties page.
default-fed-id = http://localhost/sps/oauth/oauth20/

# The name of the request parameter that can be used to override the
# default-fed-id option configured above. By deleting this configuration
# option, you can enforce that the default fed id is always used.
fed-id-param = FederationId

# The name of the TFIM cluster which houses this OAuth service.  There should
# also be a corresponding [tfim-cluster:<cluster>] stanza which contains the
# definition of the cluster.
cluster-name = oauth-cluster

# The name of the attribute within the RSTR response from TFIM whose value is
# to be used as the user identity when creating the session credential.
user-identity-attribute = username

There is also a new configuration option in the [oauth-eas] stanza, and this makes it easy to disable the old EAS when using the new OAuth authentication. This option means you can still use the ISAM configuration utility to enable WebSEAL for API protection, and then just switch to OAuth authentication and disable the EAS.

Note: It is not recommended to use both OAuth authentication AND the EAS at the same time. Only use one or the other.

#
# The oauth-eas configuration stanza is used to configure the EAS which
# communicates with TFIM to handle OAuth authorization.  The EAS itself will
# be invoked for a particular object if the effective POP for the object has
# an attribute entitled "eas-trigger", with an associated value of
# "trigger_oauth_eas".
#
[oauth-eas]

# Should the EAS be enabled?
eas-enabled = false

With these options configured, WebSEAL will now build a user credential for the user from the ‘username’ attribute (as defined by the ‘user-identity-attribute’) with the full user registry credential information. This will enable standard SSO to the backend junctions.

When simply presenting just the access token, WebSEAL will revalidate the access token on every access. There are two ways to avoid this:

  • Use a client with a cookie jar, and catch the WebSEAL session cookie
  • Configure OAuth-Auth Sessions using the steps below.

Here is a sample request showing the ISAM session cookie returned to the client:

$ curl -k -v -H "Authorization: bearer 1J0EA" https://webseal/resource.jsp
*   Trying 192.168.42.202...
* Connected to webseal (192.168.42.202) port 443 (#0)
* TLS 1.2 connection using TLS_RSA_WITH_AES_128_CBC_SHA
* Server certificate: isam901
> GET /epac.jsp HTTP/1.1
> Host: webseal
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: bearer 1J0EA
> 
< HTTP/1.1 200 OK
< content-language: en-US
< content-type: text/html; charset=UTF-8
< date: Thu, 14 Jul 2016 04:59:36 GMT
< p3p: CP="NON CUR OTPi OUR NOR UNI"
< transfer-encoding: chunked
< x-global-transaction-id: 396435295
< cache-control: no-cache="set-cookie, set-cookie2"
< expires: Thu, 01 Dec 1994 16:00:00 GMT
< x-powered-by: Servlet/3.1
< session-timeout: 598
< x-backside-transport: OK OK
< Set-Cookie: PD-S-SESSION-ID=1_2_1_mTk7l4ZSgDhLCE...tV0BdLxcgsuj; Path=/; Secure; HttpOnly
<

 

Building an OAuth session from the token (Cookieless OAuth access)

For a cookieless client, a WebSEAL session can be keyed off the Access token to provide:

  • Access token validation – just once in a session.
  • Session activity keep alive.
    If the access token is used in this way, the token lifetime may reduce its expiry time.
    You can use the existing WebSEAL inactivity times for this, in combination with the session logout functionality. The session max lifetime is based on the expiry of the access token. Its possible to modify this max value dynamically in the OAuth Post Token mapping rule.
  • WebSEAL Cookie Jar, Cookies can be withheld from the client using the managed cookie list.
  • Session logout, killing the current access token and ending the session. [New in ISAM 9.0.1]
SessionAuthentication
Figure 2. OAuth Session based Authentication

To enable this feature, there are two steps:  first set “require-mpa” to no:

# Require Multiplexing Proxy Agent for HTTP Header Session Keys and
# HTTP Header authentication tokens.
#
# The use of an HTTP header as a session identifier or as an authentication
# token carries a measure of risk that the header can be spoofed or stolen.
# It is strongly recommended that headers only be accepted when proxied
# through an authenticated channel.  A 'yes' setting means that HTTP headers
# will not be valid session keys or authentication tokens unless received via
# an MPA.  Please see the WebSEAL Administration Guide for more details
# regarding MPAs.
require-mpa = no

And Define the key for the ISAM session to be the OAuth Authorization Handler:

[session-http-headers]
#----------------------
# HTTPHEADER SESSION KEYS
#----------------------
Authorization = https

OAuth Session Lifetime

The OAuth Session maximum lifetime is based on the access token’s response.

As per the ISAM 9.0.1 Whats New documentation:

OAuth Authentication session based on token lifetime

When OAuth Authentication is enabled, the WebSEAL configuration parameter session lifetime timeout, which is controlled by the timeout entry in the [session] stanza of the WebSEAL configuration file, is ignored. The session lifetime is set to the OAuth token expiry time.

This means that inactivity is important to consider, such that you may have an access token valid for 60 mins, but an inactivity of 10mins. If you would like to modify this dynamically, modify the OAuth response in the Post Token mapping rule to give the desired value.

(For example, you might set the token lifetime short in the API definition, but report a longer max lifetime value in the Post Token mapping rule to enable sessions that extend beyond life of a token based on activity.)

OAuth Session Logout

[New in ISAM 9.0.1] When the WebSEAL session expires due to inactivity, WebSEAL is configured to call the OAuth runtime and request that the access token is disabled from future validation. This is configured using the Backend server single sign off capability of WebSEAL:

#-----------------------------
# BACK-END SERVER SINGLE SIGN-OFF
#-----------------------------
# When a user's session is terminated in WebSEAL, any sessions that may exist
# on back-end application servers are not destroyed. When this item is
# configured, WebSEAL will send a request to the configured URI's including
# any configured headers and cookies for the junction point on which it resides
# The backend application can use this information to terminate any sessions
# for that user.
#
# Multiple URI's can be specified by including multiple single-signoff-uri
# configuration entries.
#
# The configured URI must reside on a standard junction. For example:
# single-signoff-uri = /app/logout.asp
#
# single-signoff-uri =
single-signoff-uri = /mga/sps/oauth/oauth20/logout

This means an OAuth Session can also be effectively closed/ended by navigating to the standard WebSEAL /pkmslogout URL.

https://webseal/pkmslogout

 

Distributed Session Cache

When using OAuth-Auth, it’s not currently possible to use the Distributed Session Cache. If your instance of WebSEAL DSC enabled the cookie returned in the request will override the Access token.

# Enable/disable use of the DSC.  If this is set to yes the "dsess" stanza
# must have information about how to communicate with the DSC.
dsess-enabled = no

Adding OAuth attributes to the ISAM credential

Any attributes returned from the ISAM for Mobile OAuth mapping rule in the format of:

//Add a custom attribute to the ISAM users credential
stsuu.addContextAttribute(new Attribute("custom_attribute", 
            "urn:ibm:names:ITFIM:oauth:response:attribute", "some_value"));

will be added to the users credential.

Note: With the old EAS implementation, any attribute returned using the above format, would automatically be converted into a header and sent with the request down to the junction.

By default in the OAuth authentication process attributes are only sent down the junction in the encrypted ISAM credential (when configured to send iv-creds) to the junctioned server. In order to send them as a HTTP Header, see the steps detailed in the next two sections.

OK: Sending OAuth attributes as a header manually

In order to replicate the old behaviour of the EAS and send the OAuth response attributes from the mapping rule as headers in plain text, use a feature that has been in WebSEAL for a long time. HTTP Tag Values. HTTP Tag Values allow the user to access attributes from the credential and send the values as a HTTP Header.

Note: Take a special note of the requirement of the “tagvalue_” prefix in the linked Knowledge Center pages.

These are documented in the Knowledge Center here:
IBM Security Access Manager for Web > Configuring>Configuring Access Manager for Web > Configuring Web Reverse Proxy > Authentication > Credential processing > Extended attributes for credentials > Junction handling of extended credential attributes

Configuring a HTTP Tag Value can be done via pdadmin, or via the Web Portal Manager, this is configured on a per junction basis. For sending OAuth attributes with all requests, see the next section.

Better: Sending OAuth attributes as a header automatically

You can elect to always send attributes down the junction using an additional flag in your javascript mapping rule “tagvalue_always”.

IBM Security Access Manager for Web 8.0.0.4 > Configuring > Configuring Access Manager for Web > Configuring Web Reverse Proxy > Authentication > Credential processing > Extended attributes for credentials > Junction handling of extended credential attributes > tagvalue_always extended attribute

So for example, to always send the custom attribute “custom_attribute” as a HTTP header with the request, we would add the following line in our javascript mapping rule:

//Add a custom attribute to the ISAM users credential
stsuu.addContextAttribute(new Attribute("custom_attribute", 
            "urn:ibm:names:ITFIM:oauth:response:attribute", "some_value"));
stsuu.addContextAttribute(new Attribute("tagvalue_always", 
            "urn:ibm:names:ITFIM:oauth:response:attribute", "custom_attribute"));

Using the WebSEAL tracing component pdweb.debug you can validate that the headers are supplied in the request:

----- trace.pdweb.debug:2 ----------------- PD ===> BackEnd 
GET /test/api/postpin/viewAccounts.jsp HTTP/1.1
connection: close
host: host
iv-user: testuser1
user-agent: Dalvik/1.6.0 (Linux; U; Android 4.2.2; sdk Build/JB_MR1.1)
via: HTTP/1.1 isam:444
custom_attribute: some_value
iv_server_name: wga-webseald-isam
Cookie: PD_STATEFUL_5c7e53f6-b30b-11e3-8d6e-000c2931096b=%2Fmga

---------------------------------------------------

The EAS was configured to send the following attributes by default:

HEADER: username HEADERVALUE: testuser1
HEADER: access_token HEADERVALUE: xKOzCJaE9TWE96vAdcwb
HEADER: oauth_token_client_id HEADERVALUE: ZtwIDmdJqlE3B7Ool9au
HEADER: authorized HEADERVALUE: TRUE
HEADER: scope HEADERVALUE: balance,phone
HEADER: client_type HEADERVALUE: public
HEADER: Expires HEADERVALUE: 2013-02-15T01:47:48Z

So the mapping rule configured to replicate this behavior would be the following:

stsuu.addContextAttribute(new Attribute("tagvalue_always", 
     "urn:ibm:names:ITFIM:oauth:response:attribute", 
     "username,access_token,oauth_token_client_id,authorized,scope,client_type,"+
     "Expires"));

Such that the WebSEAL debug trace would appear as follows:

----- trace.pdweb.debug:2 ----------------- PD ===> BackEnd 
GET /test/api/postpin/viewAccounts.jsp HTTP/1.1
connection: close
host: host
iv-user: testuser1
user-agent: Dalvik/1.6.0 (Linux; U; Android 4.2.2; sdk Build/JB_MR1.1)
via: HTTP/1.1 isam:444
username: testuser1
access_token: xKOzCJaE9TWE96vAdcwb
oauth_token_client_id: ZtwIDmdJqlE3B7Ool9au
authorized: TRUE
scope: balance,phone
client_type: public
Expires: 2013-02-15T01:47:48Z
iv_server_name: wga-webseald-isam
Cookie: PD_STATEFUL_5c7e53f6-b30b-11e3-8d6e-000c2931096b=%2Fmga
---------------------------------------------------

This concludes the discussion on OAuth Authentication, to consider OAuth Authorization with WebSEAL, see my new article OAuth Authorization with ISAM.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

WordPress.com.

Up ↑

%d bloggers like this: