OpenIG 3.1, minor release but loads of improvements

This blog post was first published @ sauthieg.github.io, included here with permission.

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 lied when I said it was Christmas ;)

Console Logs

I can’t resists 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 accordingly 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 correspond 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 enable 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

©2019 ForgeRock - we provide an identity and access platform to secure every online relationship for the enterprise market, educational sector and even entire countries. Click to view our privacy policy and terms of use.

Log in with your credentials

Forgot your details?