Cumulative Statistics with Identity Gateway

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission. How healthy is your Identity Gateway? How healthy are the downstream applications it protects. Cough, cough – one might think. IG Studio allows to easily enable statistics collection. Data is cumulative since server startup or over recent time intervals. Statistics-based health checking is not just if endpoints are […]

Message Capture with OpenIG

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission.

Setting up protection for a web application or API is much easier if you know what is actually going on between client and server.

OpenIG functions by the concept of a reverse web proxy, primarily with the objective to enforce authentication and authorization. However it also allows to simply log inbound and outbound messages to a file.

The OpenIG Studio provides a straightforward way to configure capture inbound and outbound messages.

 

The capture is logged by default in the route-rocksock.log file. In this example, openig.example.com is the external hostname which hits OpenIG. The internal hostname is internal.company.com. This is not know to the client but configured in the route configuration for /rocksock in OpenIG.

 

 

 
The route-rocksock.log file from the example :

--- (request) id:0307be7f-3166-4dde-bf08-698dd82c2c5b-178 --->    

GET http://openig.example.com:8080/rocksock/ HTTP/1.1
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-encoding: gzip, deflate
accept-language: en;q=1,de;q=0.9,en-US;q=0.8,fr-FR;q=0.7,it;q=0.6
connection: keep-alive
host: openig.example.com:8080
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:36.0) Gecko/20100101 Firefox/36.0 SeaMonkey/2.33.1

--- (request) id:0307be7f-3166-4dde-bf08-698dd82c2c5b-178 --->

GET http://internal.company.com:9080/rocksock/ HTTP/1.1
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-encoding: gzip, deflate
accept-language: en;q=1,de;q=0.9,en-US;q=0.8,fr-FR;q=0.7,it;q=0.6
connection: keep-alive
host: openig.example.com:8080
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:36.0) Gecko/20100101 Firefox/36.0 SeaMonkey/2.33.1

<--- (response) id:0307be7f-3166-4dde-bf08-698dd82c2c5b-178 ---

HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 42
Content-Type: text/html
Date: Tue, 25 Oct 2016 16:13:48 GMT
ETag: W/"42-1477411512000"
Last-Modified: Tue, 25 Oct 2016 16:05:12 GMT

[entity]

<--- (response) id:0307be7f-3166-4dde-bf08-698dd82c2c5b-178 ---

HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 42
Content-Type: text/html
Date: Tue, 25 Oct 2016 16:13:48 GMT
ETag: W/"42-1477411512000"
Last-Modified: Tue, 25 Oct 2016 16:05:12 GMT

[entity]

The route configuration as produced by the OpenIG Studio looks as follows :

{
  "name": "rocksock",
  "baseURI": "http://internal.company.com:9080",
  "condition": "${matches(request.uri.path, '^/rocksock')}",
  "monitor": false,
  "capture": [
    "request",
    "response"
  ],
  "heap": [
    {
      "type": "ClientHandler",
      "name": "ClientHandler",
      "capture": [
        "request",
        "response"
      ]
    }
  ],
  "handler": "ClientHandler"
}
The IG studio will be shipped with ForgeRock Identity Gateway 5.0. For more, see the OpenIG Studio introduction .

 

Introducing OpenIG Studio

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission.

According to the Twelve-Factor App, OpenIG [1] configuration is considered code [2]. Organizations are driving towards “headless” deployment models meaning that beyond the development stage, administration consoles or management APIs are disabled. It’s the continuous integration and delivery pipeline which takes care of bringing a change from development to production in an automated way.

With this in mind and combined with the need to simplify the creation of OpenIG application protections (routes), we decided build an IDE-type utility, the OpenIG studio. OpenIG studio allows to visually build application or API protection (aka route) enabling message capture, throttling, authentication, authorization and statistics gathering. Further, OpenIG studio allows to do rapid prototyping of what is being built.

You can test drive the OpenIG studio without hassle via Docker. It only takes a couple of docker commands to get OpenIG running. Then point a browser to http://localhost:8080/openig/studio and create an application/API protection.

 

You can export the configuration (ehem code) and then feed your source code management system (e.g. git) and ultimately the continuous delivery pipeline.

For example :

 {
  "name": "rocksock",
  "baseURI": "http://internal.company.com:9080",
  "condition": "${matches(request.uri.path, '^/rocksock')}",
  "monitor": false,
  "handler": "ClientHandler"
}

Now that the configuration (ehem code) is built, how to rapidly test it ? As the studio is packaged with the OpenIG war file, the new configuration can be pushed to this running OpenIG instance. Press “Deploy” !

What all these configuration options are useful for, how to shut down the studio in production deployments and how to deal with deployment environment specific parameters merit separate contemplation.

The studio will be shipped with ForgeRock Identity Gateway 5.0.

Notes

[1] OpenIG is an identity gateway integrating (legacy) applications with modern digital identity tokens and procedures. Based on a reverse proxy type architecture, it can enforce authentication and authorization for access to web applications or APIs.
[2] With the exception for deployment environment specific settings. OpenIG provides a way to deal with this following Twelve-Factor App recommendations.

OpenIG on Docker: The Perfect Couple

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission.

“Docker containers wrap a piece of software in a complete filesystem that contains everything needed to run […]” [1]


OpenIG (Open Identity Gateway) provides an elegant yet flexible way to integrate your applications, devices, APIs with modern identity standards such as token types, authentication and authorization. The gateway as your integration component can be deployed and scaled along the applications and services it secures.

Whilst organizations adopt containerization as part of a “well-oiled” delivery pipeline, which includes the gateway, OpenIG in a container is also very beneficial for evaluation purposes. Here’s how you can evaluate in just a couple of minutes.

As prerequisites, you need docker and git on your system.

  1. Checkout the ForgeRock docker project to retrieve the Dockerfile and sample OpenIG configuration files
  • git clone https://stash.forgerock.org/scm/docker/docker.git
  • cd docker/openig
  • Build the docker image
  • docker build -t forgerock/openig:latest .
  • Run the docker image and mount the sample-config directory from your local git copy in the container
  • docker run –detach -p 8080:8080 –volume <LOCAL_PATH_TO_GIT>/docker/openig/sample-config:/var/openig –name openig -it forgerock/openig
To test the sample configuration, point your client (e.g. web browser, curl) to http://localhost:8080/simplethrottle for instance. The response is determined by the StaticResponseHandler setting in the 20-simplethrottle.json file.
A simplified version of this procedure however without the sample configuration but not necessitating usage of git and clone the full repo goes as follows. This is well suited to evaluate the upcoming user interface.
  1. Download the Dockerfile from https://stash.forgerock.org/projects/DOCKER/repos/docker/browse/openig/Dockerfile
  2. Build the docker image (as above)
  • docker build -t forgerock/openig:latest .
  • Run the docker image
  • docker run -d -p 8080:8080 –name openig -it forgerock/openig
Other useful commands:
  • Start container: docker stop openig
  • Stop container: docker start openig
  • Get shell prompt: docker exec -i -t openig /bin/bash
  • Remove container: docker rm openig

References

[1]Package your application into a standardized unit for software development”. Retrieved from https://www.docker.com/what-docker on Sep 6th, 2016.

 

Unlocking the Authorization Asset

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission.

Consumer identity is a core asset to your business. Unlocking authorization and leveraging it into your business processes and (micro) services helps you in this endeavor as it drives a yet higher level of personalization and how users interact with resources and objects.

In a recent post titled “Authorization for Everything” I outlined how any resource or object can be described in ForgeRock’s identity platform authorization framework by the example of a home cinema.

But who’s going to setup the authorization objects and controls ?
(Question by an attendee of the ForgeRock Identity Summit in Düsseldorf)

User facing applications that operate or control devices or resources, like mobile applications or smart remote controls, are now enabled to call directly in the authorization framework to manage or evaluate permissions. This is also possible go via a hub to which an appliance like the home cinema would register when it is plugged in.

Smart authorization is now unlocked to any of these procedures, services and applications regardless of the platform. And the key is the REST API provided by the ForgeRock identity platform.

The key to drive authorization in the user experience or device management is the API !
Implement it where it creates most value for the consumer.
(My answer)

In full detail now how to manage and evaluate authorization elements via REST by the example of a home cinema.

Authorization Management via REST in detail
Step 1: Creating a resource type TV

First we create a resource type TV and specify the format of how to address the resource (e.g. tv://myhouse/homecinema) and possible actions for the resource.

Request:
curl -s –request POST –header “Content-Type: application/json” –data @request.json https://sso.redstone.com:443/sso/json/authzrealm/resourcetypes?_action=create&_prettyPrint=true
Request (JSON):
{
“patterns”: [
“tv://*/*”
],
“name”: “tv”,
“actions”: {
“ENABLE”: true,
“DISABLE”: true,
“BROADCAST SCREEN”: true,
“BROADCAST CAMERA”: true
}
}
Response (JSON):
{
“uuid” : “9fefc18f-5731-4963-a8d6-fa8aba7923d4”,
“name” : “tv”,
“description” : null,
“patterns” : [ “tv://*/*” ],
“actions” : {
“DISABLE” : true,
“ENABLE” : true,
“BROADCAST CAMERA” : true,
“BROADCAST SCREEN” : true
},
“createdBy” : “id=amadmin,ou=user,dc=sso-config,dc=com”,
“creationDate” : 1447989190178,
“lastModifiedBy” : “id=amadmin,ou=user,dc=sso-config,dc=com”,
“lastModifiedDate” : 1447989190178
}
Note the resource type’s UUID in the response. This value is needed later to assign a resource type to a policy.


Step 2: Creating the policy set (or application)

Next the resource set (or application) needs to be created with the resourceTypeUUID containing the one of resource type TV.

Request:
curl -s –request POST –header “Content-Type: application/json” –data @request.json https://sso.redstone.com:443/sso/json/authzrealm/applications?_action=create&_prettyPrint=true
Request (JSON):
{    “name” : “SmartHome”,
“applicationType” : “iPlanetAMWebAgentService”,
“description” : “Controlling objects in a smart home.”,
“resourceTypeUuids” : [ “9fefc18f-5731-4963-a8d6-fa8aba7923d4”],
“subjects” : [ “Policy”, “NOT”, “OR”, “JwtClaim”, “AuthenticatedUsers”, “AND”, “Identity”, “NONE” ],
“entitlementCombiner” : “DenyOverride”,
“saveIndex” : null,
“searchIndex” : null,
“resourceComparator” : null,
“attributeNames” : [ ],
“editable” : true,
“conditions” : [ “LEAuthLevel”, “Policy”, “Script”, “AuthenticateToService”, “SimpleTime”, “AMIdentityMembership”, “OR”, “IPv6”, “IPv4”, “SessionProperty”, “AuthScheme”, “AuthLevel”, “NOT”, “AuthenticateToRealm”, “AND”, “ResourceEnvIP”, “LDAPFilter”, “OAuth2Scope”, “Session” ]
}
Response (JSON):
{
“lastModifiedBy” : “id=amadmin,ou=user,dc=sso-config,dc=com” ],
“lastModifiedDate” : 1447989192860,
“creationDate” : 1447989192860,
“createdBy” : “id=amadmin,ou=user,dc=sso-config,dc=com”,
“applicationType” : “iPlanetAMWebAgentService”,
“subjects” : [ “Policy”, “NOT”, “OR”, “JwtClaim”, “AuthenticatedUsers”, “AND”, “Identity”, “NONE” ],
“entitlementCombiner” : “DenyOverride”,
“saveIndex” : null,
“searchIndex” : null,
“resourceComparator” : null,
“attributeNames” : [ ],
“editable” : true,
“conditions” : [ “LEAuthLevel”, “Policy”, “Script”, “AuthenticateToService”, “SimpleTime”, “AMIdentityMembership”, “OR”, “IPv6”, “IPv4”, “SessionProperty”, “AuthScheme”, “AuthLevel”, “NOT”, “AuthenticateToRealm”, “AND”, “ResourceEnvIP”, “LDAPFilter”, “OAuth2Scope”, “Session” ],
“description” : “Controlling objects in a smart home.”,
“name” : “SmartHome”
}
Step 3: Creating the policy giving permissions to Bob

Next the resource set (or application) needs to be created with the resourceTypeUUID containing the one of resource type TV.

Request:
curl -s –request POST –header “Content-Type: application/json” –data @request.json https://sso.redstone.com:443/sso/json/authzrealm/policies?_action=create&_prettyPrint=true
Request (JSON):
{
“name” : “HomeCinema”,
“active” : true,
“description” : “”,
“applicationName” : “SmartHome”,
“actionValues” : {
“ENABLE” : true,
“DISABLE” : true,
“BROADCAST SCREEN” : true,
“BROADCAST CAMERA” : true
},
“resources” : [ “tv://myhouse/homecinema” ],
“subject” : {
“type” : “Identity”,
“subjectValues” : [ “id=bob,ou=user,o=authzrealm,ou=services,dc=sso-config,dc=com” ]
},
“resourceTypeUuid” : “9fefc18f-5731-4963-a8d6-fa8aba7923d4”
}
Response (JSON):
{
“name” : “HomeCinema”,
“active” : true,
“description” : “”,
“applicationName” : “SmartHome”,
“actionValues” : {
“DISABLE” : true,
“ENABLE” : true,
“BROADCAST CAMERA” : true,
“BROADCAST SCREEN” : true
},
“resources” : [ “tv://myhouse/homecinema” ],
“subject” : {
“type” : “Identity”,
“subjectValues” : [ “id=bob,ou=user,o=authzrealm,ou=services,dc=sso-config,dc=com” ]
},
“resourceTypeUuid” : “9fefc18f-5731-4963-a8d6-fa8aba7923d4”,
“lastModifiedBy” : “id=amadmin,ou=user,dc=sso-config,dc=com”,
“lastModifiedDate” : “2015-11-20T03:13:14.274Z”,
“createdBy” : “id=amadmin,ou=user,dc=sso-config,dc=com”,
“creationDate” : “2015-11-20T03:13:14.274Z”
}
Step 4: Evaluating the policy for user Bob

Next the resource set (or application) needs to be created with the resourceTypeUUID containing the one of resource type TV. For completeness – the procedure is already outlined in “Authorization for Everything” – here’s how an upstream application would evaluate if Bob can broadcast the screen (or any other action). 

Request URL:

https://sso.redstone.com:443/sso/json/authzrealm/policies?_action=evaluateTree&_prettyPrint=true

Request (JSON):
{
“application”: “SmartHome”,
“resource”: “tv://myhouse/homecinema”,
“subject”: {
“ssoToken”: “AQIC5wM2LY4SfcxbXJgKBtBsbzH0OtxslnEQDHK2RJ5UJho.*AAJTSQACMDIAAlNLABQtOTIwMDUyMDgxMTA2Mzk1NjIzMgACUzEAAjAx*”
}
}
Response (JSON):
[ {
“advices” : { },
“ttl” : 9223372036854775807,
“resource” : “tv://myhouse/homecinema”,
“actions” : {
“DISABLE” : true,
“ENABLE” : true,
“BROADCAST CAMERA” : true,
“BROADCAST SCREEN” : true
},
“attributes” : { }
} ]

If you want to go further, look at the details of policy creation via REST, policy evaluation or maybe even reproduce my demo at the Identity Summit in Düsseldorf, check the openam-high5 GitHub project. In particular the 652-authz-create-policy and 654-authz-evaluate-policy-tv.

 

Authorization for Everything

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission.

Smart contextual & conditional authorization lowers barriers enabling friction-less user on-boarding, more intuitive user journeys and ultimately increases your return on identity, right at the heart of your digital transformation strategy.
Moving beyond web and mobile application security, for any object, any action, any context, authorization shall be described. It’s ForgeRock’s identity platform that does provide you the framework. It provides you Authorization for Everything.

The model, principals and functionality can be applied to any business, so as an example, I describe authorization for an “ordinary” object, a family household. It is composed of the family members and family members and household appliances. Bob stores wine in his wine cabinet, not only for consumption, but also for investments. Inventory is thus a crucial as Bob wants to know the current value of his investments. Other “critical” resources are the screens. For the home cinema, we can image specific actions like turn on and off as well as broadcasting screen or camera. Not all family member should have the same permissions to these resources.

  

Authorization Management

The HomeCinema policy contains resources, actions, subjects and conditions. The whole Smith family is allowed to turn on and off the home cinema between 16h00 and 19h00. Bob should add a policy that allows him to operate the home cinema after 19h00 and broadcast the camera with his remote friends when football is on. Here’s how it looks in the OpenAM administration interface :

Any kind of resource with any kind of action can be described in the authorization framework, be it real estate, contracts, online media, etc. It a later post I shall describe how this can be done via API (REST), so that policy creation could be part of the resource or device registration process handled by application above the identity platform.

 

Policy Evaluation

Policy evaluation for a given resource and subject can be done via API. The policy enforcement point (which could be the home cinema itself but also a mobile app) requests a policy decision via REST. The user must be authenticated in some form prior to this request. The user’s SSO token is then added to the policy evaluation request.
Request URL:
https://sso.redstone.com:443/sso/json/authzrealm/policies?_action=evaluateTree&_prettyPrint=true
Request:

{
“application”: “SmartHome”,
“resource”: “tv://myhouse/homecinema”,
“subject”: {
“ssoToken”: “AQIC5wM2LY4Sfcw5j9MI_A6GO7s58XGwY7yTAuEeP4RJcvM.*AAJTSQACMDIAAlNLABQtOTAyNzM0MDcxNzQ3NDU3MTE4MAACUzEAAjAx*”
}
}

Response:

[ {
“advices” : { },
“ttl” : 9223372036854775807,
“resource” : “tv://myhouse/homecinema”,
“actions” : {
“DISABLE” : true,
“ENABLE” : true,
“BROADCAST CAMERA” : false,
“BROADCAST SCREEN” : false
},
“attributes” : { }
} ]
The user is only allow to turn the home cinema on and off, not to broadcast screen or camera. Any objects, actions, subjects, context and conditions can be described in the identity platform. Unlocking the authorization asset on top of your customer view enables an even more personalized experience.

If you want to look at the details of the policy evaluation request and how it fits in the authorization framework, check the openam-high5 GitHub project. In particular the 654-authz-evaluate-policy-tv or 655-authz-evaluate-policy-door  scripts.

Device Fingerprints for Mobile Applications

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission.

Browser fingerprints play a useful role to make security more convenient (refer to
Smarter Security with Device Fingerprints“). The concept can be extended to any device, especially non-browser clients.

The client (mobile application for example) itself collects and includes fingerprint information in the authentication request. The authentication server (OpenAM) matches and eventually saves the device fingerprint as it would do with the browser fingerprint.

Device Fingerprints in the Authentication Process

A custom device fingerprint can be as simple as the following :
{
“telephoneNumber”: “+33123456789”
}
Based on the authentication process in the aforementioned article, the DeviceId (Match) authentication module gets adapted to include a function for telephone number match. See the openam-telephonenumber-deviceprint-serverscript.js file for inspiration. OpenAM supports the full authentication process via REST. Refer to “REST on every side” for the detailed steps.
Note that the out-of-the-box DeviceId (Save) authentication module can be used “as-is” for for privacy and consent.

Based on that, the device fingerprint can take any form, be signed or encrypted, as long as the corresponding DeviceId (Match) module can appropriately compare with stored fingerprints.[1]

In case you want to build this example or something similar, I published scripts for the purpose of inspiration within the openam-high5 GitHub project, in particular 630-custom-deviceprint-base-config, 631-deviceid-rest-telephonenumber.

References

[1] Die drei Fragezeichen, Fingerabdrücke, Kosmos, 2010

 

REST on every side

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission.

Regardless if web application, mobile application, device application or thing application development – identity management is there for you. Be it internal or external. The fast way in is REST. ForgeRock’s identity management platform delivers through REST. I’ll illustrate by example authentication via REST against a complex authentication chain.

“Representational State Transfer (REST) is a software architecture style for building scalable web services.” [1] [2]

The Authentication Chain
OpenAM’s authentication service can be composed of multiple authentication modules. The authentication chain consists 4 authentication modules including LDAP and device fingerprint. The relevance of such a chain was discussed in a previous article titled “Smarter Security with Device Fingerprints”.
For the purpose of simplicity, the OneTimePassword is replaced with a DataStore authentication module. Rather than providing a one time password (e.g. SMS passcode), the user has to provide username and password (same or different than before depending on the OpenAM configuration).
As there is no browser involved, any json structure can be sent back as the fingerprint.
The authentication process consists of 6 steps if no corresponding and valid device fingerprint was previously registered. In case it was, the authentication finishes after step 3.

The Tools: CURL, JQ and the Scripts
As client in this example serves the straightforward curl tool. This allows easy investigation of requests and responses.
Note that the JWT (JSON Web Token) needs to be passed on between all callbacks. For extracting specific elements of json, like the JWT, the jq tool can be of great use (for instance JWT_TOKEN=`echo ${CURL_RESPONSE} | jq –raw-output ‘.authId’`).
In case you want to build this example or something similar, I published in a GitHub project  scripts which could be of inspiration (see in particular 620-deviceid-base-config, 621-deviceid-rest-base, 622-deviceid-rest-ootb).

The Authentication Steps in Detail [3]
Step 1: Get the authentication token
An “empty” request is sent to obtain the JWT (JSON Web Token) and the first set of callbacks.

Request
curl -s –request POST –header “Content-Type: application/json” https://sso.yellowstone.com:443/sso/json/authenticate?realm=/deviceidrealm
Response

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "LDAP1",
  "header": "Sign in to OpenAM",
  "callbacks": [
    {
      "type": "NameCallback",
      "output": [
        {
          "name": "prompt",
          "value": "User Name:"
        }
      ],
      "input": [
        {
          "name": "IDToken1",
          "value": ""
        }
      ]
    },
    {
      "type": "PasswordCallback",
      "output": [
        {
          "name": "prompt",
          "value": "Password:"
        }
      ],
      "input": [
        {
          "name": "IDToken2",
          "value": ""
        }
      ]
    }
  ]
}

Step 2: Provide callbacks for LDAP module
The JWT is passed with any subsequent request in this authentication process. Username and password are passed as required by the LDAP authentication module’s callback.

Request
curl -s –request POST –header “Content-Type: application/json” –data @callback-step2.json https://sso.yellowstone.com:443/sso/json/authenticate?realm=/deviceidrealm
callback-step2.json :

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "LDAP1",
  "callbacks": [
    {
      "type": "NameCallback",
      "output": [
        {
          "name": "prompt",
          "value": " User Name: "
        }
      ],
      "input": [
        {
          "name": "IDToken1",
          "value": "demo"
        }
      ]
    },
    {
      "type": "PasswordCallback",
      "output": [
        {
          "name": "prompt",
          "value": " Password: "
        }
      ],
      "input": [
        {
          "name": "IDToken2",
          "value": "changeit"
        }
      ]
    }
  ]
}

Response
After successful LDAP authentication, the JavaScript which computes the fingerprint is sent in the TextOutputCallback.

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "DeviceIdMatch2",
  "header": "Sign in to OpenAM",
  "callbacks": [
    {
      "type": "HiddenValueCallback",
      "output": [
        {
          "name": "value",
          "value": ""
        }
      ],
      "input": [
        {
          "name": "IDToken1",
          "value": "clientScriptOutputData"
        }
      ]
    },
    {
      "type": "TextOutputCallback",
      "output": [
        {
          "name": "message",
          "value": "JAVASCRIPT TO BE EXECUTED IN THE CLIENT BROWSER. OMITTED FOR READABILITY"
        },
        {
          "name": "messageType",
          "value": "4"
        }
      ]
    }
  ]
}

Step 3: Provide callbacks for DeviceId (Match) module
The fingerprint is sent back to the authentication process through the HiddenValueCallback. As there is no browser involved, any json element can be sent in. Note that the value element is of type String and the String contains the json. So properly encode the json (i.e. escape double quotes).

Request
curl -s –request POST –header “Content-Type: application/json” –data @callback-step3.json https://sso.yellowstone.com:443/sso/json/authenticate?realm=/deviceidrealmcallback-step3.json :

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "DeviceIdMatch2",
  "callbacks": [
    {
      "type": "HiddenValueCallback",
      "input": [
        {
          "name": "IDToken1",
          "value": "THE FINGERPRINT GATHERED "
        }
      ]
    },
    {
      "type": "TextOutputCallback",
      "output": [
        {
          "name": "messageType",
          "value": "4"
        }
      ]
    }
  ]
}
Response

If the fingerprint corresponds to a registered fingerprint, then the authentication process would return successfully at this point. Otherwise (in this case), a second factor is required (DataStore module).

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "DataStore1",
  "header": "Sign in to OpenAM",
  "callbacks": [
    {
      "type": "NameCallback",
      "output": [
        {
          "name": "prompt",
          "value": "User Name:"
        }
      ],
      "input": [
        {
          "name": "IDToken1",
          "value": ""
        }
      ]
    },
    {
      "type": "PasswordCallback",
      "output": [
        {
          "name": "prompt",
          "value": "Password:"
        }
      ],
      "input": [
        {
          "name": "IDToken2",
          "value": ""
        }
      ]
    }
  ]
}

Step 4: Provide callbacks for DataStore module
Request
curl -s –request POST –header “Content-Type: application/json” –data @callback-step4.json https://sso.yellowstone.com:443/sso/json/authenticate?realm=/deviceidrealm

callback-step4.json :

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "DataStore1",
  "callbacks": [
    {
      "type": "NameCallback",
      "output": [
        {
          "name": "prompt",
          "value": " User Name: "
        }
      ],
      "input": [
        {
          "name": "IDToken1",
          "value": "demo"
        }
      ]
    },
    {
      "type": "PasswordCallback",
      "output": [
        {
          "name": "prompt",
          "value": " Password: "
        }
      ],
      "input": [
        {
          "name": "IDToken2",
          "value": "changeit"
        }
      ]
    }
  ]
}
Response 

Now that both factors succeeded, the user is asked whether to store the device fingerprint or not.

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "DeviceIdSave2",
  "header": "Add to Trusted Devices",
  "callbacks": [
    {
      "type": "ChoiceCallback",
      "output": [
        {
          "name": "prompt",
          "value": "Add to Trusted Devices?"
        },
        {
          "name": "choices",
          "value": [
            "Yes",
            "No"
          ]
        },
        {
          "name": "defaultChoice",
          "value": 1
        }
      ],
      "input": [
        {
          "name": "IDToken1",
          "value": 1
        }
      ]
    }
  ]
} 

Step 5: Provide callbacks for DeviceId (Save) module – Consent to store device profile
The value 0 in the ChoiceCallback indicates that the user want to store the device fingerprint with his profile.

Request
curl -s –request POST –header “Content-Type: application/json” –data @callback-step5.json https://sso.yellowstone.com:443/sso/json/authenticate?realm=/deviceidrealm 
callback-step5.json :

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "DeviceSave2",
  "callbacks": [
    {
      "type": "ChoiceCallback",
      "input": [
        {
          "name": "IDToken1",
          "value": "0"
        }
      ]
    }
  ]
}
Response

Then the user is prompted to provide a name under which the new profile shall be stored.

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "DeviceIdSave3",
  "header": "Trusted Device Name",
  "callbacks": [
    {
      "type": "NameCallback",
      "output": [
        {
          "name": "prompt",
          "value": "Trusted Device Name?"
        }
      ],
      "input": [
        {
          "name": "IDToken1",
          "value": ""
        }
      ]
    }
  ]
}

Step 6: Provide callbacks for DeviceId (Save) module – Device profile name
Then If an empty Then If an empty v is provided as the device name, the authentication module will compute one which looks like “Profile: 21/08/2015 15:51”.
Request
curl -s –request POST –header “Content-Type: application/json” –data @callback-step6.json https://sso.yellowstone.com:443/sso/json/authenticate?realm=/deviceidrealm 
callback-step6.json :

{
  "authId": "eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.eyAib3RrIjogImdvbGhwOHFrNDVtbTI5cm91YWpyOHI2b2dkIiwgInJlYWxtIjogIm89ZGV2aWNlaWRyZWFsbSxvdT1zZXJ2aWNlcyxkYz1zc28tY29uZmlnLGRjPWNvbSIsICJzZXNzaW9uSWQiOiAiQVFJQzV3TTJMWTRTZmN5dDJ5VTFoc3J1OHZNZkhzVW1hMjd1QjA0S3YtQk5iZEUuKkFBSlRTUUFDTURJQUFsTkxBQk10TlRrek9UQXlOek0yTURJME1EZ3lNakkyQUFKVE1RQUNNREUuKiIgfQ.ZQGuCe3qDUEchsxcDCLdRU73g1i-isUAZDdp5ZOvVdM",
  "template": "",
  "stage": "DeviceIdSave3",
  "callbacks": [
    {
      "type": "NameCallback",
      "input": [
        {
          "name": "IDToken1",
          "value": ""
        }
      ]
    }
  ]
} 
Response
Now the response contains an SSOToken. This means the authentication was successful.
{
  "tokenId": "AQIC5wM2LY4SfczOURj5zOskLzpSNfuSU9GYnW5XTu8Tudg.*AAJTSQACMDIAAlNLABM2OTIyMTc1MTIwOTUxMTA2NTcxAAJTMQACMDE.*",
  "successUrl": "/sso/console"
}

“And the LORD gave them rest on every side”. Joshua 21:44 [4]

 

References

[1] Pautasso, Cesare; Wilde, Erik; Alarcon, Rosa (2014), REST: Advanced Research Topics and Practical Applications
[2] Wikipedia contributors. “Representational state transfer.” Wikipedia, The Free Encyclopedia. Wikipedia, The Free Encyclopedia, 1 Sep. 2015. Web. 1 Sep. 2015.
[3] Craig, Mark; Goldsmith, David; Hirayama, Gene: Lee, Chris, et al. OpenAM Developer’s Guide Version 13.0.0-SNAPSHOT. ForgeRock, AS., 2015. <http://openam.forgerock.org/openam-documentation/openam-doc-source/doc/webhelp/dev-guide/rest-api-auth-json.html>
[4] The Holy Bible, New International Version, NIV Copyright 1973, 1978, 1984, 2011 by Biblica

Smarter Security with Device Fingerprints

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission.

Smarter security also means user friendly security, moving security beyond compromising convenience.

Multi-factor authentication has many benefits. Going through multiple factors multiple times in a same day from the same device, makes users grumble, especially when working at the office all day. Security can be smarter than that.

It happens to be that web browsers in the hand of individual users develop an increasing level of uniqueness based on a combination of parameters such as browser type, installed fonts and plugins, resolution and colour depth, timezone, preferred language, and even geolocation. All these elements (and potentially others) combined represent the browser fingerprint.

So the user who has already authenticated in the morning using username, password and SMS passcode as a 2nd factor comes back from lunch. A more convenient single factor authentication (username and password) can often be suitable if the user is using from the same device. In reality, users authenticate more often than that against the same system the same day.

The National Institute of Standards and Technology (NIST) researched the friction and disruption created by authentication. It concludes that any authentication task that requires time and effort on the part of the user creates a “wall of disruption” that impedes the performance of primary tasks, even when there are no problems [1].

Besides implementing SSO, device fingerprints are a compelling asset to lower the “wall of disruption.” ForgeRock’s identity platform provides this functionality right out of the box (since OpenAM 12). On top, browser fingerprint collection, matching and storing can be customized and extended. The functionality is part of the commercial and open source, as smart security software should be.

As privacy is built into ForgeRock’s DNA and products, device fingerprints are stored with user consent and the user can view and delete them anytime.

Device Fingerprints in the Authentication Process

OpenAM provides two authentication modules to support device or browser fingerprint. First, the “Device ID (Match)”  module, which invokes the collection of the fingerprint via JavaScript (executed in the user’s web browser), compares the collected fingerprint with stored fingerprints and determines if the device can be considered as known. And second the  “Device ID (Save)” module, which stores, if appropriate, the newly collected fingerprint in the data store.

Device fingerprint authentication is used in combination with other authentication modules with the goal to spare users multiple factors of authentication. Typically users are challenged with a first factor like username password. Only if this succeeds will the fingerprint then be collected and compared with stored fingerprints. If the device is not “known,” the user will face a second factor of authentication like one-time-password via SMS. Only after the second factor succeeded, and upon user consent, will the fingerprint then be stored. If however the device is “known,” no further processing is necessary and user authentication succeeded.

The OpenAM Admin Guide has a bunch of further hints on how to chain the device ID modules with other modules [2].

Privacy and Consent

Before storing a device fingerprint, the user is asked for consent. If a user does not decide to store browser fingerprints, then the device fingerprint modules have no effect and the authentication continues as defined in the authentication chain. Stored browser fingerprints can be managed as “Trusted Devices” by the enduser through the enduser dashboard. By default, device fingerprints have a lifetime of 30 days.

Inside the Device Fingerprint Module

The “DeviceID (Match)” module stores the collected fingerprint in the shared state memory element of the authentication modules (key is devicePrintProfile). This value is picked up by the “DeviceID (Save)” module (if the process gets that far)  from the shared state and then stored in the data store.
Browser fingerprints are stored in the user datastore. For instance, with the embedded store (by default) in the multi-valued attribute devicePrintProfiles in the following form (“pretty printed”):

{
  "lastSelectedDate": 1437623008779,
  "devicePrint": {
    "screen": {
      "screenWidth": 1440,
      "screenHeight": 900,
      "screenColourDepth": 24
    },
    "timezone": {
      "timezone": -120
    },
    "plugins": {
      "installedPlugins": "widevinecdmadapter.plugin;mhjfbmdgcfjbbpaeojofohoefgiehjai;PepperFlashPlayer.plugin;internal-remoting-viewer;internal-nacl-plugin;internal-pdf-viewer;"
    },
    "fonts": {
      "installedFonts": "cursive;monospace;serif;sans-serif;fantasy;default;Arial;Arial Black;Arial Narrow;Arial Rounded MT Bold;Comic Sans MS;Courier;Courier New;Georgia;Impact;Papyrus;Tahoma;Times;Times New Roman;Trebuchet MS;Verdana;"
    },
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36",
    "appName": "Netscape",
    "appCodeName": "Mozilla",
    "appVersion": "5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36",
    "platform": "MacIntel",
    "product": "Gecko",
    "productSub": "20030107",
    "vendor": "Google Inc.",
    "language": "en-US",
    "geolocation": {
      
    }
  },
  "name": "MacBookChrome",
  "selectionCounter": 1,
  "uuid": "a85e66e4-5de3-4795-be43-7159e9590cbb"
}

As mentioned before, the collection and matching can be extended and customised.

Further Reading

The Electronic Frontier Foundation published an interesting article “How Unique Is Your Web  Browser?”  in which, amongst other topics, research on diversity and stability of browser fingerprints is exposed. It concludes :

“Browser fingerprinting is a powerful technique, and fingerprints must be considered alongside cookies, IP addresses and supercookies when we discuss web privacy and user trackability. Although fingerprints turn out not to be particularly stable, browsers reveal so much version and configuration information that they remain overwhelmingly trackable. There are implications both for privacy policy and technical design. Policymakers should start treating fingerprintable records as potentially personally identifiable, and set limits on the durations for which they can be associated with identities and sensitive logs like clickstreams and search terms.” [3]  Note that the default device fingerprint authentication modules support expiration of fingerprints.

Further research on the topic of browser fingerprinting shows alternative ways to compute a fingerprint. For instance, using HTML5 <canvas> elements [4] – and ways for users to circumvent fingerprinting, if they desire. The ForgeRock Identity Platform can cater to both methodologies, as it is open and extensible and honors privacy.

References

[1] Steves, M; Chisnell, D; Sasse, A; Krol, K; Theofanos, M; Wald, H; (2014) Report: Authentication Diary Study. (NIST Interagency or Internal Reports (NISTIR) NIST IR 7983 ). <http://dx.doi.org/10.6028/NIST.IR.7983>
[2] Goldsmith, David; Hirayama, Gene: Lee, Chris, et al. OpenAM Administration Guide, Version 12.0.0. ForgeRock, AS., December 17, 2014. August 28, 2015. <http://docs.forgerock.org/en/openam/12.0.0/admin-guide/index/chap-auth-services.html#device-id-match-hints>
[3] Eckersley, Peter; How Unique Is Your Web Browser? Electronic Frontier Foundation, 2010 <https://panopticlick.eff.org/browser-uniqueness.pdf>
[4] Mowery, Keaton and Shacham Hovav. Pixel Perfect: Fingerprinting Canvas in HTML5.  <http://w2spconf.com/2012/papers/w2sp12-final4.pdf>
[5] Wikipedia contributors. Device fingerprint. Wikipedia, The Free Encyclopedia. Wikipedia, The Free Encyclopedia, 27 Jul. 2015. Web. 28 Aug. 2015.

By Joachim Andres