OpenAM 12.0.0 released

OpenAM logo

This past Thursday ForgeRock released OpenAM 12.0.0, a major update with so many improvements and new features that this post only hits a few highlights. You can download OpenAM 12.0.0 from http://forgerock.com/download-stack/.

OpenAM provides an access management solution handling authentication and authorization for all sorts of applications, no doubt including yours. OpenAM does SSO with delegated authentication to over 20 authn services out of the box, authorization both though centralized policies and also using delegated approaches (OAuth 2.0, etc.), security token brokering and more. OpenAM supports a rich set of standards like SAML, OAuth 2.0, OpenID Connect, GSMA Mobile Connect, not to mention standards for authentication. Of course OpenAM is open source and fully extensible as well. The OpenAM service runs as a web application in a variety of containers such as JBoss, Tomcat, WebLogic and WebSphere. OpenAM policy enforcement agents give you out-of-the box protection for many web sites and web applications, though you can also do your own enforcement using OpenAM’s REST APIs.

As a major release, OpenAM 12.0.0 is leap forward in many areas:

  • Default end user pages now use responsive, client-side layout with lots of self-service features (self-registration, password reset, app management, etc.) ready to go.
  • Wizards make it a snap to delegate authentication to Facebook, Google, MSN and other online providers.
  • Policy administration works through a new wizard-based editor, and both policy administration and policy evaluation have well-defined REST APIs for all operations.
  • Script language support for authentication modules let your scripted modules call out to other applications using JavaScript or Groovy, making it easier to integrate external risk management in addition to OpenAM’s built-in capabilities.
  • Security token services now come with a REST API.
  • OpenAM supports OAuth 2.0 and OpenID Connect 1.0 more fully than before, with additional support for GSMA Mobile Connect.
  • And much more…

To see the whole list of features, start by reading the Release Notes for details. Full documentation is available on docs.forgerock.org.

When you start using OpenAM 12.0.0 and find that you have questions, in addition to the mailing list ForgeRock also now provides an OpenAM Forum. We look forward to hearing from you.


OpenIG 3.0 Migration CLI

ForgeRock OpenIG 3.1 has been recently released (12th of December, on time ;) ) and it's time for you to give it a try! Already done that ? Great! But wait a minute, what are all theses deprecation warning messages you see on the logs ?

WED DEC 17 16:46:03 CET 2014 (WARNING) file:/.../config/config.json
The configuration field heap/objects has been deprecated. Heap objects should now be listed directly in the top level "heap" field, e.g. { "heap" : [ objects... ] }.
------------------------------
WED DEC 17 16:46:03 CET 2014 (WARNING) file:/.../config/config.json
[/] The 'handlerObject' attribute is deprecated, please use 'handler' instead
------------------------------

Don't worry, these messages are only warnings, your old configurations are still parseable by OpenIG 3.1: everything is backward compatible, we just warn you that, in the next major release, theses elements are likely to be unsupported (in other words, they would probably be ignored).

Hopefully, in order to reduce the burden of migrating your config files manually, which is always an error-prone operation, I wrote a small toolkit that will massage your existing JSON configuration and produce a 3.1 compatible JSON.

At time of writing, the openig-migration toolkit supports the following migration actions:

  • heap/objects array has been simplified to just heap
  • Heap object declaration inline (when possible)
  • Remove "config": {} (empty element)
  • Rename RedirectFilter to LocationHeaderFilter
  • Rename handlerObject to handler
  • Rename OAuth2ResourceServerFilter deprecated attributes to new names

Usage

As there is still no binary available, you have to build the binary yourself (make sure you use a JDK 8 at both compile and runtime):

git clone https://github.com/sauthieg/openig-migration.git
cd openig-migration
mvn clean install

Then, you have to execute it: it expects a path to the JSON document to migrate:

java -jar target/openig-migration-1.0-SNAPSHOT-jar-with-dependencies.jar .../config.json

This command line outputs the transformed JSON on System.out.

Example

This example is extracted from OpenIG 3.0 documentation:

{
  "heap": {
    "objects": [
      {
        "name": "DispatchHandler",
        "type": "DispatchHandler",
        "config": {
          "bindings": [
            {
              "condition": "${exchange.request.uri.path == '/login'}",
              "handler": "LoginChain",
              "baseURI": "http://TARGETIP"
            },
            {
              "handler": "OutgoingChain",
              "baseURI": "http://TARGETIP"
            }
          ]
        }
      },
      {
        "name": "LoginChain",
        "type": "Chain",
        "config": {
          "filters": [
            "LoginRequest"
          ],
          "handler": "OutgoingChain"
        }
      },
      {
        "name": "LoginRequest",
        "type": "StaticRequestFilter",
        "config": {
          "method": "POST",
          "uri": "https://TARGETIP/login",
          "form": {
            "USER": [
              "myusername"
            ],
            "PASSWORD": [
              "mypassword"
            ]
          }
        }
      },
      {
        "name": "OutgoingChain",
        "type": "Chain",
        "config": {
          "filters": [
            "CaptureFilter"
          ],
          "handler": "ClientHandler"
        }
      },
      {
        "name": "CaptureFilter",
        "type": "CaptureFilter",
        "config": {
          "captureEntity": false,
          "file": "/tmp/gateway.log"
        }
      },
      {
        "name": "ClientHandler",
        "comment": "Responsible for sending all requests to remote servers.",
        "type": "ClientHandler",
        "config": {}
      }
    ]
  },
  "handlerObject": "DispatchHandler"
}

... and is migrated to:

{
  "heap": [
    {
      "name": "DispatchHandler",
      "type": "DispatchHandler",
      "config": {
        "bindings": [
          {
            "condition": "${exchange.request.uri.path == '/login'}",
            "handler": {
              "name": "LoginChain",
              "type": "Chain",
              "config": {
                "filters": [
                  {
                    "name": "LoginRequest",
                    "type": "StaticRequestFilter",
                    "config": {
                      "method": "POST",
                      "uri": "https://TARGETIP/login",
                      "form": {
                        "USER": [
                          "myusername"
                        ],
                        "PASSWORD": [
                          "mypassword"
                        ]
                      }
                    }
                  }
                ],
                "handler": "OutgoingChain"
              }
            },
            "baseURI": "http://TARGETIP"
          },
          {
            "handler": "OutgoingChain",
            "baseURI": "http://TARGETIP"
          }
        ]
      }
    },
    {
      "name": "OutgoingChain",
      "type": "Chain",
      "config": {
        "filters": [
          {
            "name": "CaptureFilter",
            "type": "CaptureFilter",
            "config": {
              "captureEntity": false,
              "file": "/tmp/gateway.log"
            }
          }
        ],
        "handler": {
          "name": "ClientHandler",
          "comment": "Responsible for sending all requests to remote servers.",
          "type": "ClientHandler"
        }
      }
    }
  ],
  "handler": "DispatchHandler"
}

Notice the now inlined object declaration that make it easier to follow the execution flow and understand what happen to your request. The empty un-necessary elements have been removed too.

Limitations

At time of writing, some old JSON files may be incorrectly handled by the migration CLI:

  • Incorrectly escaped regular expressions (in EntitytExtractFilter)
  • Multi-line Strings (without a line ending )

Contributions

Feel free to open issues, and/or fork the repository for any improvements you can think of.

I'll be happy to consider all pull requests.

Happy hacking !

OpenIG 3.1.0 released

openig-logo This past Friday ForgeRock released OpenIG 3.1.0, an official minor release for which you can get support from ForgeRock. You can download OpenIG 3.1.0 from http://forgerock.com/download-stack/.

OpenIG is a reverse proxy with session management and credential replay functionality. It runs as a web application in Apache Tomcat or Jetty. By using OpenIG you can provide identity and access management solutions for just about any web application, and you can do it without touching the web application itself. OpenIG supports standards like OAuth 2.0, OpenID Connect 1.0, and SAML 2.0, and of course integrates well with ForgeRock’s software stack. Furthermore, OpenIG is extensible through built-in Groovy support and Java plugin points.

As a minor release, OpenIG 3.1.0 is backward compatible with 3.0.0 so you can try it with your existing configuration.

You can then start to take advantage of new features:

  • A JWT session implementation lets you store all state on the client side as long as it fits in a browser cookie whose value is the session data in an encrypted JWT. OpenIG holds the keys for encryption and decryption to prevent anyone else from accessing the session data. By delegating storage of all state data to the user-agent, you can scale out your deployment without having to configure OpenIG’s container to share session data.
  • Inline configuration objects and other improvements make OpenIG configuration files easier to read.
  • Configuration object decorators make it straightforward to capture requests, responses, and exchange data, to time operations, and to audit OpenIG operations.
  • A publish-and-subscribe audit framework and sample monitoring handler returns basic statistics about OpenIG operations.
  • Other improvements make console logs easier to read, script parameters easier to set, OAuth 2.0/OpenID Connect filters more performant, and client information easier to discover.

Start with the Release Notes for details. Full documentation is available on docs.forgerock.org. Also check out the articles written by Ludo and Guillaume.

When you have questions, in addition to the mailing list ForgeRock also now provides an OpenIG Forum. Stop by to let us know what you think of OpenIG 3.1.0.


OpenIG 3.1 is now available…

It’s my great pleasure to announce the general availability of OpenIG 3.1, a minor update of the ForgeRock Open Identity Gateway product, following the press release of early December.

The Open Identity Gateway is a simple standard-based solution to secure access to web applications and APIs. It supports SAMLv2, OAuth 2.0, OpenID Connect and can capture and replay credentials, enabling SSO and Federation.

With a four months release cycle since the previous release, OpenIG 3.1 doesn’t contain many major new features, but it does bring several new enhancements to the product, including :

  • The support for encrypted JSON Web Token (JWT) cookies to store session information on the user-agent. The administrator can decide to keep the default container managed sessions, or use JWT cookies globally or for a specific route.
  • A simplification of OpenIG configuration, with the ability to inline objects, omit specific fields when empty or obvious. This simplification enables faster configuration as well as a better readability for long term maintenance of the service.
  • IMG_4090The introduction of “Decorator” for configuration objects, easily adding new behaviors to existing configured objects. OpenIG 3.1 provides 3 decorators out of the box: a CaptureDecorator that enables debugging and logging in a much easier and more dynamic way; a TimerDecorator that records times spent in the decorated objects; an AuditDecorator that allows to audit operations for any decorated objects.
  • The support for a sample monitoring handler that provides basic statistics about the exchanges and routes. The monitoring information can be used to provide an activity dashboard such as here on the right..
  • Some optimisations and performance improvements when using OpenID Connect and OAuth 2.0

For the complete details of the changes in OpenIG 3.1, please check the release notes.

You can download the ForgeRock product here. It’s been heavily tested by our Quality Assurance team : functional tests on Windows, Mac and Linux, stress tests as proxy, with OAuth2 and OpenID Connect, non-regression tests… The documentation has been entirely reviewed and all examples tested.  The  source code is available in our code repository (https://svn.forgerock.org/openig).

We are interested in your feedback, so get it, play with it and give us your comments, either on the mailing list, the wiki, the OpenIG Forum or through blog posts.

 


Filed under: Identity Gateway Tagged: API, authentication, authorization, ForgeRock, gateway, identity, identity gateway, openig, opensource, release

OpenIG 3.1, minor release but loads of improvements

Ho ho ho, Christmas is happening sooner this year! I'm very pleased to announce OpenIG 3.1. This minor release focused on usability improvements, monitoring enablement, session management and, obviously ... bug fixing.

For this Christmas release, the OpenIG team has been very hard at work during the last weeks to deliver (on time) a delightful version.

Improve configuration file readability/usability

We learned the hard way that trying to understand the config.json and sibling route's configuration files can gives headaches! Mentally representing a graph of objects when its representation is completely flat (a list with named pointers) is too hard.

So we decided to make it easier: life will be easier for you when writing your configurations and for us when you'll send your not-working configurations for debug ;)

Here is the list of improvements in regards to the ease of configuration:

  • Object declarations can be inlined: when an attribute is a reference to another defined heap object, you can now directly include the whole object configuration in place of the object name. Notice that inlining only makes sense when the referenced object is not used elsewhere in your configuration.
    • Inline declarations don't require a name attribute (but this is still useful for identifying source objects when looking at log messages)
    • If your configuration just has one main handler (as it's usually the case), you can even omit the heap object array and directly define your object inside of the handler element
  • Empty "config": { } elements can be removed
  • Aligned configuration attributes to use the same name when possible:
    • OAuth 2.0 Client and ResourceServer filter have been aligned on providerHandler, requireHttps, cacheExpiration and scopes (that is now, in both cases, a list of Expression instead of just String)
    • config.json: handlerObject is now handler (like in route config files)

Better with an example, here is your config before:

{
  "heap": {
    "objects": [
      {
        "name": "Chain",
        "type": "Chain",
        "config": {
          "filters": [
            "ReplaceHostFilter"
          ],
          "handler": "Router"
        }
      },
      {
        "name": "ReplaceHostFilter",
        "type": "HeaderFilter",
        "config": {
          "messageType": "REQUEST",
          "remove": [
            "host"
          ],
          "add": {
            "host": [
              "example.com"
            ]
          }
        }
      },
      {
        "name": "Router",
        "type": "Router",
        "config": {}
      }
    ]
  },
  "handler": "Chain"
}

And now:

{
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "HeaderFilter",
          "config": {
            "messageType": "REQUEST",
            "remove": [
              "host"
            ],
            "add": {
              "host": [
                "example.com"
              ]
            }
          }
        }
      ],
      "handler": {
        "type": "Router"
      }
    }
  }
}

Notice that most of this tedious work can be done with the OpenIG Migration Tool.

I did not lie when I said it was Christmas ;)

Console Logs

I can't resist to show you an excerpt of your new logs (at least when you choose a ConsoleLogSink):

TUE DEC 02 17:36:10 CET 2014 (INFO) _Router
Added route 'oauth2-resources.json' defined in file '/Users/guillaume/tmp/demo/config/routes/oauth2-resources.json'
------------------------------
TUE DEC 02 17:36:11 CET 2014 (INFO) _Router
Added route 'monitor.json' defined in file '/Users/guillaume/tmp/demo/config/routes/monitor.json'
------------------------------
TUE DEC 02 17:36:12 CET 2014 (INFO) {SamlFederationHandler}/heap/1/config/bindings/0/handler
FederationServlet init directory: /Users/guillaume/tmp/demo/SAML
------------------------------
TUE DEC 02 17:36:12 CET 2014 (WARNING) SamlSession
JWT session support has been enabled but no encryption keys have been configured. A temporary key pair will be used but this means that OpenIG will not be able to decrypt any JWT session cookies after a configuration change, a server restart, nor will it be able to decrypt JWT session cookies encrypted by another OpenIG server.
------------------------------
TUE DEC 02 17:36:12 CET 2014 (INFO) _Router
Added route 'wordpress-federation.json' defined in file '/Users/guillaume/tmp/demo/config/routes/wordpress-federation.json'
------------------------------
TUE DEC 02 17:36:19 CET 2014 (ERROR) _Router
The route defined in file '/Users/guillaume/tmp/demo/config/routes/openid-connect-carousel.json' cannot be added
------------------------------
TUE DEC 02 17:36:19 CET 2014 (ERROR) _Router
/heap/0/type: java.lang.ClassNotFoundException: ConsoleLogSinkA
[       JsonValueException] > /heap/0/type: java.lang.ClassNotFoundException: ConsoleLogSinkA
[   ClassNotFoundException] > ConsoleLogSinkA
------------------------------
TUE DEC 02 17:36:46 CET 2014 (WARNING) {HttpClient}/heap/2/config/httpClient
[/heap/2/config/httpClient/config] The 'truststore' attribute is deprecated, please use 'trustManager' instead
------------------------------

The logs are now much more readable and concise: the first line is a header line and gives you the log timestamp (date formatted according to your Locale), the message's log level and its source name (name of the heap object that produced the message), then you have the message itself until the blank line separator is reached.

The attentive reader noticed that Exception messages are handled in a different way: each line corresponds to a summary of an exception in the chain, up to the root cause.

If the ConsoleLogSink is configured with the DEBUG level, the full exception stack-trace will be printed, instead of just the condensed rendering.

Performances

On the performance side, there were also a number of enhancements:

  • A brand new clustering section has been added in the documentation. After reading this, the technics to load-balance OpenIG and configure it for fail-over will have no secrets for you. This doc tells you how to achieve this with Tomcat and Jetty as examples.
  • OAuth 2.0 caches enablement: the OAuth2ResourceServerFilter was already capable of caching token info data from the IDP, minimizing the network latency, now the OAuth2ClientFilter is able to cache (and load on-demand) the content of the user-info endpoint.
  • JWT Session support, in other word: how to deport session storage from server-side to client-side without sacrificing confidentiality. This technic for storing session data outside of the server is perfect when you want scalability: no content is stored on server, so it is stateless and can be replicated easily. JSON Web Tokens are used to have both an easily serializable and deserializable session format and to reach message confidentiality (the content is encrypted, only OpenIG can read it again).

Features

OK, we couldn't resist to add at least a few new features in OpenIG 3.1!

The most core one is decorator support: this feature enables an easy way to add behaviours to existing heap objects without having to change the code of theses objects.

Let's have the following example: in OpenIG 3.0, when you wanted to capture the messages flowing in and out of a given Handler, you had to:

  • Create a CaptureFilter
  • Create a Chain, configure it with the CaptureFilter and using your observed handler as terminal handler
  • Update the source reference to your observed handler to use the Chain name

Definitely not user-friendly, and in 3.0 there was no inline heap object declaration, making this process even more tedious :'(

{
  "heap": {
    "objects": [
      {
        "name": "Chain",
        "type": "Chain",
        "config": {
          "filters": [
            "CaptureFilter"
          ],
          "handler": "Observed"
        }
      },
      {
        "name": "CaptureFilter",
        "type": "CaptureFilter",
        "config": {
          "file": "..."
        }
      },
      {
        "name": "ConsumerOfObserved",
        "type": "....",
        "config": {
          "handler": "Chain"
        }
      },
      {
        "name": "Observed",
        "type": "ClientHandler",
        "config": { }
      }
    ]
  }
}

Now, in 3.1, you just add a capture decorator in your observed object declaration and you're done!

{
  "heap": [
    {
      "name": "Observed",
      "type": "ClientHandler",
      "capture": [ "request", "response" ]
    }
  ]
}

You just added a capture decorator to the Observed object, now for each object invokation, the decorator will be called and will do its job (here capturing the Exchange's content). Easier !

A number of decorators are available out-of-the-box:

  • capture: as seen earlier this permit easy route debugging and error finding
  • timer: compute the time spent inside of objects for performance tracking
  • audit: track messages inside of the system (monitoring)

Monitoring

Monitoring how your service is behaving is now as easy as it should be :)

Thanks to the decorator framework, your can audit your routes and receive notifications when observed components (or routes) are traversed.

This is just as simple as adding an audit 'tag' to your route configuration, (this is used to qualify the notifications):

{
  "handler": {
    "...": "..."
  },
  "audit": [ "wordpress" ]
}

Then, you just add a route that activates the MonitoringEndpointHandler (a simple audit agent), just like what @markcraig explained in his blog.

At the end, you should have a nice monitoring console:

Monitoring Console See @ludomp blog for details on the monitoring console.

Thanks

Let finish with a huge thanks to all involved in producing this release: developers, QA engineers, technical writers, architects, product managers, ...!

Now it's up to you to confirm this success: download and try it by yourself :)

And have nice Christmas vacations!

Resources

New features in OpenIG 3.1: Statistics

OpenIGOpenIG 3.1 is almost out the doors… Just a few days of testing and it will be generally available.

The new version introduces a general purpose auditing framework, and some basic monitoring capabilities. Mark wrote a blog post describing the details of the auditing framework and the monitoring endpoint. I’ve started playing with it for demonstration purposes and wanted to get more out of it.

If you want to expose the monitoring endpoint, you need to add the following 00-monitor.json file under .openig/config/routes/ and decorate a few handlers as Mark describes in his post. You might also want to extend this configuration to require authentication and avoid letting anyone have access to it.

The monitoring endpoint allows to display basic statistics about the different routes: the counts of in progress requests, completed requests and failures. So the output looks like this:

{"Users":{"in progress":0,"completed":6,"internal errors":0},
 "main":{"in progress":1,"completed":1074,"internal errors":0},
 "groups":{"in progress":0,"completed":4,"internal errors":0},
 "Default":{"in progress":0,"completed":16,"internal errors":0},
 "monitor":{"in progress":1,"completed":1048,"internal errors":0}
}

Each tag represents a route in OpenIG, including the “monitor” one,  “main” representing the sum of all routes.

I was thinking about a better way to visualise the statistics and came up with the idea of a monitoring console. A few lines of Javascript, using JQuery and Bootstrap, an additional configuration file for OpenIG and here’s the result:

Screen Shot 2014-12-09 at 13.15.18

As you can see, this adds a new endpoint with its own audit: /openig/Console. The endpoint can be protected like any other route using OAuth2.0, OpenID Connect, SAML or basic authentication.

Let’s look at what I’ve done.

I’ve added a new route under ~/.openig/config/routes: 00-console.json with a single StaticResponseHandler. Instead of adding the whole content in the json file, I’ve decided to let the handler load the whole content from a file (named console.html). This allows me to separate the logic from the content.

00-console.json

{
    "handler":{
        "type": "StaticResponseHandler",
        "config" : {
            "status": 200,
            "entity": "${read('/Users/ludo/.openig/config/routes/console.html')}"
        }
    },
    "condition": "${exchange.request.method == 'GET'
        and exchange.request.uri.path == '/openig/Console'}",
    "audit" : "Console"
}

Note that if you are copying the 00-console.json file, you will need to edit the file location to match the absolute path of your console.html file.

Now the console.html file is actually a little bit long to display here. But you can download it here.

But it’s a basic html page, which loads Jquery and Bootstrap:

<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
...

And at regular interval (default is 3 seconds), it gets the statistics from the monitoring endpoint, and displays them as a table:

...
<script>
$(document).ready(function () {
    setInterval(function () {
        $.get("/openig/monitor").success(writeRoutesStats);
    }, 3000);
});
...

The whole Console fits within 60 lines of html and javascript, including some logic to use different colours when internal errors occur on a route.

Finally, the nice thing about the Console, being based on BootStrap, it also has responsive design and allows me to monitor my OpenIG instance from anywhere, including my phone:IMG_4090

If you do install the Console on your instance of OpenIG 3.1 (or one of the latest nightly builds), please send me a screenshot. And if you do customize the javascript for an even nicer look and feel, don’t hesitate to send a pull request.


Filed under: Identity Gateway Tagged: console, dashboard, ForgeRock, identity gateway, monitoring, openig, opensource

OpenAM: REST APIs for policy evaluation

OpenAM logo

One of the significant new features added to OpenAM and coming in the pending release is the new REST API for policy evaluation. To try the API, get a nightly build of OpenAM, or build the code yourself from the trunk.

Some background: Your application should not be in the business of making policy decisions. Not because you are not smart enough to do it, but instead because you do not want to maintain potentially intricate and changing policies across all your applications. Instead your application should ask a service like OpenAM to make policy decisions, and then focus only on enforcing those policy decisions. (In fact, if your application runs in a web server or application server, you could do even better by getting a policy agent to do the work on your application’s behalf.) You can therefore administer policies within the service like OpenAM, and have them uniformly enforced across many applications. Policy evaluation is what your application asks a policy decision point like OpenAM to carry out.

OpenAM has had REST APIs for policy evaluation for a long time. The older APIs required, however, that you re-encode the SSO token in a particular way. They also did not necessarily return JSON, making them a bit more difficult to work with.

The newer API returns JSON, and does not require tokens to be re-encoded. The newer API makes use of two endpoints:

  1. /json/policies?_action=evaluate (for myRealm/subRealm, /json/myRealm/subRealm/policies?_action=evaluate)
    This endpoint takes an HTTP POST, where the POST data is a JSON object defining the “resources”, “application”, “subject”, and “environment” for which OpenAM makes the policy decision.

    • The “resources” in this case is an array of strings specifying the resource(s), such as "http://www.example.com/profile", that the user is trying to access. This is the only required field.
    • The “application” is the policy application name. You see the application names in the new policy editor. Policies belong to applications, so the application name narrows down the set of policies that can apply.
    • The “subject” can take an SSO token ID string to represent the subject, but it can also take a JWT or a map of JWT claims, depending on how the policies are configured in OpenAM.
    • The optional “environment” can provide additional information about the environment of the user who is trying to access the resource.
  2. /json/policies?_action=evaluateTree (for myRealm/subRealm, /json/myRealm/subRealm/policies?_action=evaluateTree)
    This endpoint takes an HTTP POST with POST data similar to the first. Instead of “resources”, it takes a “resource” string. OpenAM returns policy decisions about all the resources under the specified “resource”.

Suppose you have a policy in OpenAM that belongs to the default application and that allows authenticated users GET access to "http://www.example.com/profile", returning the user’s common name as a response attribute.

In addition, you have a web page that allows you to get a policy decision when logged in as a user authorized to request policy decisions, such as OpenAM administrator. (This example is overly simplistic and mixes up content with policy enforcement. In real life, your client-side JavaScript would end up requesting a resource; your server-side policy enforcement code would check with OpenAM before responding.)

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>

<h3>Fake Profile Page</h3>

<div id="common-name"></div>
<div id="policy-decision"></div>
<div id="error"></div>

<script type="text/javascript">

var endpoint  =
  "http://openam.example.com:8080/openam/json/policies?_action=evaluate";
var resources =
  '{ "resources": [ "http://www.example.com/profile" ] }';

$(document).ready(function () {

  // Request decision from OpenAM.
  $.ajax({

    url: endpoint,
    type: "POST",
    contentType: "application/json",
    dataType: "json",
    data: resources

  }).done(function (data) {

    // Display the name.
    $("#common-name").html(
      "<h4>Common Name</h4>"
      + "<pre>"
      + data[0].attributes.cn
      + "</pre>"
    );

    // Display the full response.
    $("#policy-decision").html(
      "<h4>Policy Decision</h4>"
      + "<pre>"
      + JSON.stringify(data, undefined, 2)
      + "</pre>"
    );

  }).fail(function (data) {

    // Display the error response.
    $("#error").html(
      "<h4>Error:</h4>"
      + "<pre>"
      + JSON.stringify(data, undefined, 2)
      + "</pre>"
      );
    });
});

</script>

</body>
</html>

If you first login to OpenAM as amadmin in order to get a session cookie and then visit the web page, you can get a policy decision for the specified resource.

policy

For details on the API, see the draft documentation on Requesting Policy Decisions.


Google and OAuth 2.0 Compatibility (Eliminate all other factors, and the one which remains must be the truth. (Sherlock Holmes))

Over the weekend I was pinged by my QA engineers about new failures in our OAuth 2.0 test suite. Not a good sign, just a few days before the OpenIG 3.1 release date ! Anyway, I've made my hands dirty to track down the problem up to the source. Here is the story :)

This issue has been fixed the 12th of December 2014 (see stack overflow answer).

Everything starts with ...

... a failure, at least I had the screenshot of a nice Exception, pretty explicit by the way:

The failure

... then you start digging

... on your side. Yeah, you must have done something wrong in your code, Google is just working (Apple ©), right ?

The part of the code referred by that stack trace is dealing with the Access Token Response JSON structure returned from the OAuth 2.0 Token endpoint. But this has not been changed since it was first checked in (or almost, nothing recent at least), and the QA tests that were failing on friday have been working previously.

I've tried to think about every code checkin' to see the potential impact on the expected behaviour, found nothing.

On the QA side, they re-run an older OpenIG's version (that was working, remember ?), and now it's failing too !?

WTF ?

... looking more closely to what Google send

At that point, it's time to open your IDE and debug OpenIG, this way we'll see what see OpenIG see...

No wonder, it's really receiving a successful access token response of the following form:

{
  "access_token": "ya29.1gD56tBWtHW3K7oZ0FINTnsqa4VYiE2YGZeQXgJ4ID79E-mZxNWoyYi7pKrs_Vyxj8FZbuxh_RGTJw",
  "token_type": "Bearer",
  "expires_in": "3600",
  "refresh_token": "1/dGjGYC7sDFaBwpdUVpkJP2mYFYTU8HAh7T6szsKGYTs"
}

expires_in is really a String, even if semantically it's a Number !

Ok Google is now sending a String instead of a Number for this attribute.

My world collapse: Google can't be wrong for something that simple !

That reminds me a famous Sherlock Holmes quote: Eliminate all other factors, and the one which remains must be the truth.

Sad...

... what about the spec ?

As per the OAuth 2.0 Spec, a successful response looks like the following:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "token_type":"example",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "example_parameter":"example_value"
}

They even give a syntax for expires_in attribute:

expires-in = 1*DIGIT

Pretty simple, though ?

... let's find a solution

Hopefully, it was not very hard to fix: I just made one of our class a little bit smarter (dealing especially with the String case).

Tested and committed, ready for the release :)

... wait a minute, what changed on Google's side ?

They seem to have updated their OAuth 2.0 service implementation.

Take a look at the OpenID Connect Discovery endpoint returned JSON:

{
  "issuer": "accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/auth",
  "token_endpoint": "https://www.googleapis.com/oauth2/v3/token",
  "userinfo_endpoint": "https://www.googleapis.com/plus/v1/people/me/openIdConnect",
  "revocation_endpoint": "https://accounts.google.com/o/oauth2/revoke",
  "jwks_uri": "https://www.googleapis.com/oauth2/v2/certs",
  "response_types_supported": [
    "code", "token", "id_token",
    "code token", "code id_token", "token id_token", "code token id_token",
    "none"
  ],
  "subject_types_supported": [ "public" ],
  "id_token_alg_values_supported": [ "RS256" ]
}

And, more closely to the token_endpoint value: it's using a v3 API. It's not even advertised on the Google API Explorer (yet ?).

Another hint that something changed was in the last edited timestamp at the bottom of the OpenIDConnect and OAuth2WebServer google developers pages:

Edited on Friday the 5th

Funny facts

I played with Google OAuth Playground this morning (BTW, it's pretty neat and usable, good stuff).

Surprisingly, when you choose the Google OAuth endpoints set, you'll see they're not using the v3 one yet: they're using https://accounts.google.com/o/oauth2/token.

When manually re-configured to use the v3 API, you clearly see the String:

Configured with v3 endpoints

Links

The Persistent Cookie Authentication Module

How long should a session last?

I guess we all get fed up when we are asked to log in to a web site over, and over again. So when protecting your resources, it is important that an admin chooses the "right" session length.

But what is "right" depends on your resources and how tightly you'd like to protect them. Some people might want a short session length because the content may be extremely valuable and you want the user to prove that he is still the same guy.

But for other sites and resources, you may want to err on the side of convenience for the user and have a long session lifetime, maybe even stretching beyond the lifetime of a browser session. For example, the "Remember me for a week" feature seen here...


If you want to provide a long-lived session, you might want to consider the OpenAM 12 Persistent Cookie authentication module.

Here's how it could work:

Administrator experience

  1. Create a new Persistent Cookie authentication module and set the length of your session. (Note to self - Remember that if you use a Secure Cookie, the session must be over https else the browser will not submit it.)
  2. Create an authentication chain (here called "test")with the Persistent Cookie module first and mark it as sufficient.
  3. On the same Authentication Chain page, add the Persistent Cookie auth module to the Post authentication processing class for this chain. 
  4. Assign the chain to the realm you want this to work with.

User Experience

  1. The first time the user hits your site there will be no persistent cookie so the chain means you'll fall through to login using the usual method (whatever that is).
  2. On a successful login, the Post Authentication processing will store a persistent cookie. You can examine this using cookie tools like the Cookies app for Chrome or Firefox.
  3. Close the browser, logout of your PC, make a cup of tea, whatever.
  4. When you next start up the browser and return to the site you will get straight to your resources and this will continue to happen for the configured lifetime of the Persistent Cookie.
In case you're interested, the Persistent Cookie is a JWT and by default is called "session-jwt", and you can also mess around with idle times too, but this is left as an exercise to the reader ;-)

Hope this helps someone out there.
-FB

The Persistent Cookie Authentication Module

How long should a session last?

I guess we all get fed up when we are asked to log in to a web site over, and over again. So when protecting your resources, it is important that an admin chooses the "right" session length.

But what is "right" depends on your resources and how tightly you'd like to protect them. Some people might want a short session length because the content may be extremely valuable and you want the user to prove that he is still the same guy.

But for other sites and resources, you may want to err on the side of convenience for the user and have a long session lifetime, maybe even stretching beyond the lifetime of a browser session. For example, the "Remember me for a week" feature seen here...


If you want to provide a long-lived session, you might want to consider the OpenAM 12 Persistent Cookie authentication module.

Here's how it could work:

Administrator experience

  1. Create a new Persistent Cookie authentication module and set the length of your session. (Note to self - Remember that if you use a Secure Cookie, the session must be over https else the browser will not submit it.)
  2. Create an authentication chain (here called "test")with the Persistent Cookie module first and mark it as sufficient.
  3. On the same Authentication Chain page, add the Persistent Cookie auth module to the Post authentication processing class for this chain. 
  4. Assign the chain to the realm you want this to work with.

User Experience

  1. The first time the user hits your site there will be no persistent cookie so the chain means you'll fall through to login using the usual method (whatever that is).
  2. On a successful login, the Post Authentication processing will store a persistent cookie. You can examine this using cookie tools like the Cookies app for Chrome or Firefox.
  3. Close the browser, logout of your PC, make a cup of tea, whatever.
  4. When you next start up the browser and return to the site you will get straight to your resources and this will continue to happen for the configured lifetime of the Persistent Cookie.
In case you're interested, the Persistent Cookie is a JWT and by default is called "session-jwt", and you can also mess around with idle times too, but this is left as an exercise to the reader ;-)

Hope this helps someone out there.
-FB