Enabling Assertion Encryption to OpenIG SAML

OpenIG SAML code is based upon the OpenAM Fedlet code which means much of the documentation and examples found around Fedlet will work for OpenIG as a Service Provider (SP) as well.  Including this very important option of encrypting assertions in the message.

A popular use-case for OpenIG is to acquire credentials from OpenAM in order to provide them to a down-stream application as a HTTP form-post.  This configuration provides a mechanism to have encrypted assertions for OpenIG without the dependencies of a policy agent or OpenAM post authentication plug-in.

Start with basic SAML configuration with OpenAM and OpenIG, detailed here:
https://backstage.forgerock.com/docs/openig/4/gateway-guide#chap-federation

Once the standard configuration is in place and tested, one can now begin the following steps in order to update the base setup to one that supports bi-directional signing and encryption.

  1. Copy key stores and file encryption to OpenIG SAML file-structure.  For production, deployment specific certifications would be deployed.  For this example, however the copy from the IDP will work.
  2. Update SAML meta-data files on location in the OpenIG SAML file-struction.
  3. Reimport the changes into OpenAM

Go to the OpenIG SAML configuration folder:  By default located here: ~/.openig/config/SAML

Add the following under the tag of <IDPSSODescriptor> for the idp.xml

        <KeyDescriptor use="signing">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>
MIIDaDCCAlCgAwIBAgIDcB/YMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVLMRAwDgYDVQQI
EwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQKEwlGb3JnZVJvY2sxDzANBgNVBAsT
Bk9wZW5BTTENMAsGA1UEAxMEdGVzdDAeFw0xNjAzMTgxMTU2MjhaFw0yNjAzMTYxMTU2MjhaMGUx
CzAJBgNVBAYTAlVLMRAwDgYDVQQIEwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQK
EwlGb3JnZVJvY2sxDzANBgNVBAsTBk9wZW5BTTENMAsGA1UEAxMEdGVzdDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKNbl89eP6B8kZATNSPe3+OZ3esLx31hjX+dakHtPwXCAaCKqJFw
jwKdxyRuPdsVG+8Dbk3PGhk26aJrSE93EpxeqmQqxNPMeD+N0/8pjkuVYWwPIQ/ts2iTiWOVn7wz
lE4ASfvupqOR5pjuYMWNo/pd4L7QNjUCKoAt9H11HMyiP+6roo/EYgX4AH7OAhfUMncYsopWhkW/
ze9z8wTXc8BAEgDmt8zFCez1CtqJB/MlSBUGDgk8oHYDsHKmx05baBaOBQ8LRGP5SULSbRtu34eL
FootBIn0FvUZSnwTiSpbaHHRgWrMOVm07oSLWBuO3h/bj38zBuuqqVsAK8YuyoECAwEAAaMhMB8w
HQYDVR0OBBYEFHxfAbr6PQ5Xgc+jVx+AGTPnnpWZMA0GCSqGSIb3DQEBCwUAA4IBAQAZBMJ29/2i
dv1ztC6ArHtB4kw/nHHwthXFwtWAN7sRPB8tLW7fD8aJ43RQr5107Bg1Lgkmt+FZxpafqUC/mukj
IzGzbW0COMSOTcWUGss+HxK6M6Fl9aOzKJMct1uOSpPFgjItcGqydGZXR2FH93vXWoAotUwtZ119
IixIdxpOJwYJg0HFn+GEfpU1PmiLfq2/uwqJ0hGCNfNcm9puagzhQrcDFOnolxjnYPSfSkU5wxlG
o99yE5eJwoHXXU7csaZVttmx7sPj1lUENogXUM6JMqzSyEIm1XCOCL8rZJkZ781W5CwZhuJTNzV3
1sBREs8FaaCeksu7Y48BmkUqw6E9
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </KeyDescriptor>
        <KeyDescriptor use="encryption">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>
MIIDaDCCAlCgAwIBAgIDcB/YMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVLMRAwDgYDVQQI
EwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQKEwlGb3JnZVJvY2sxDzANBgNVBAsT
Bk9wZW5BTTENMAsGA1UEAxMEdGVzdDAeFw0xNjAzMTgxMTU2MjhaFw0yNjAzMTYxMTU2MjhaMGUx
CzAJBgNVBAYTAlVLMRAwDgYDVQQIEwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQK
EwlGb3JnZVJvY2sxDzANBgNVBAsTBk9wZW5BTTENMAsGA1UEAxMEdGVzdDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKNbl89eP6B8kZATNSPe3+OZ3esLx31hjX+dakHtPwXCAaCKqJFw
jwKdxyRuPdsVG+8Dbk3PGhk26aJrSE93EpxeqmQqxNPMeD+N0/8pjkuVYWwPIQ/ts2iTiWOVn7wz
lE4ASfvupqOR5pjuYMWNo/pd4L7QNjUCKoAt9H11HMyiP+6roo/EYgX4AH7OAhfUMncYsopWhkW/
ze9z8wTXc8BAEgDmt8zFCez1CtqJB/MlSBUGDgk8oHYDsHKmx05baBaOBQ8LRGP5SULSbRtu34eL
FootBIn0FvUZSnwTiSpbaHHRgWrMOVm07oSLWBuO3h/bj38zBuuqqVsAK8YuyoECAwEAAaMhMB8w
HQYDVR0OBBYEFHxfAbr6PQ5Xgc+jVx+AGTPnnpWZMA0GCSqGSIb3DQEBCwUAA4IBAQAZBMJ29/2i
dv1ztC6ArHtB4kw/nHHwthXFwtWAN7sRPB8tLW7fD8aJ43RQr5107Bg1Lgkmt+FZxpafqUC/mukj
IzGzbW0COMSOTcWUGss+HxK6M6Fl9aOzKJMct1uOSpPFgjItcGqydGZXR2FH93vXWoAotUwtZ119
IixIdxpOJwYJg0HFn+GEfpU1PmiLfq2/uwqJ0hGCNfNcm9puagzhQrcDFOnolxjnYPSfSkU5wxlG
o99yE5eJwoHXXU7csaZVttmx7sPj1lUENogXUM6JMqzSyEIm1XCOCL8rZJkZ781W5CwZhuJTNzV3
1sBREs8FaaCeksu7Y48BmkUqw6E9
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
    <xenc:KeySize xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">128</xenc:KeySize>
</EncryptionMethod>
        </KeyDescriptor>

Add the following under the tag of <IDPSSOConfig> for idp-extended.xml

        <Attribute name="signingCertAlias">
            <Value>test</Value>
        </Attribute>
        <Attribute name="encryptionCertAlias">
            <Value>test</Value>
        </Attribute>

Add the following under the tag of <SPSSODescriptor> for the sp.xml

        <KeyDescriptor use="signing">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>
MIICQDCCAakCBEeNB0swDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh
bGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMQwwCgYDVQQKEwNTdW4xEDAOBgNVBAsTB09w
ZW5TU08xDTALBgNVBAMTBHRlc3QwHhcNMDgwMTE1MTkxOTM5WhcNMTgwMTEyMTkxOTM5WjBnMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExDDAK
BgNVBAoTA1N1bjEQMA4GA1UECxMHT3BlblNTTzENMAsGA1UEAxMEdGVzdDCBnzANBgkqhkiG9w0B
AQEFAAOBjQAwgYkCgYEArSQc/U75GB2AtKhbGS5piiLkmJzqEsp64rDxbMJ+xDrye0EN/q1U5Of+
RkDsaN/igkAvV1cuXEgTL6RlafFPcUX7QxDhZBhsYF9pbwtMzi4A4su9hnxIhURebGEmxKW9qJNY
Js0Vo5+IgjxuEWnjnnVgHTs1+mq5QYTA7E6ZyL8CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB3Pw/U
QzPKTPTYi9upbFXlrAKMwtFf2OW4yvGWWvlcwcNSZJmTJ8ARvVYOMEVNbsT4OFcfu2/PeYoAdiDA
cGy/F2Zuj8XJJpuQRSE6PtQqBuDEHjjmOQJ0rV/r8mO1ZCtHRhpZ5zYRjhRC9eCbjx9VrFax0JDC
/FfwWigmrW0Y0Q==
                    </ds:X509Certificate>
                </ds:X509Data>
   </ds:KeyInfo>
        </KeyDescriptor>
        <KeyDescriptor use="encryption">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>
MIICQDCCAakCBEeNB0swDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh
bGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMQwwCgYDVQQKEwNTdW4xEDAOBgNVBAsTB09w
ZW5TU08xDTALBgNVBAMTBHRlc3QwHhcNMDgwMTE1MTkxOTM5WhcNMTgwMTEyMTkxOTM5WjBnMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExDDAK
BgNVBAoTA1N1bjEQMA4GA1UECxMHT3BlblNTTzENMAsGA1UEAxMEdGVzdDCBnzANBgkqhkiG9w0B
AQEFAAOBjQAwgYkCgYEArSQc/U75GB2AtKhbGS5piiLkmJzqEsp64rDxbMJ+xDrye0EN/q1U5Of+
RkDsaN/igkAvV1cuXEgTL6RlafFPcUX7QxDhZBhsYF9pbwtMzi4A4su9hnxIhURebGEmxKW9qJNY
Js0Vo5+IgjxuEWnjnnVgHTs1+mq5QYTA7E6ZyL8CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB3Pw/U
QzPKTPTYi9upbFXlrAKMwtFf2OW4yvGWWvlcwcNSZJmTJ8ARvVYOMEVNbsT4OFcfu2/PeYoAdiDA
cGy/F2Zuj8XJJpuQRSE6PtQqBuDEHjjmOQJ0rV/r8mO1ZCtHRhpZ5zYRjhRC9eCbjx9VrFax0JDC
/FfwWigmrW0Y0Q==
                    </ds:X509Certificate>
                </ds:X509Data>
   </ds:KeyInfo>
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
   <xenc:KeySize xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">128</xenc:KeySize>
   </EncryptionMethod>
        </KeyDescriptor>

Add the following under the tag of <SPSSOConfig> for sp-extended.xml

        <Attribute name="wantAssertionEncrypted">
            <Value>true</Value>
        </Attribute>
        <Attribute name="encryptionCertAlias">
            <Value>test</Value>
        </Attribute>

WARNING: both IDP side and SP reference a certificate alias called test note that the certificates are different.   This is because default keystore for OpenAM 13.5 is the newer JCEKS while the certificate store for OpenIG is the older style JKS.  The stores contain different certificates which same alias name, do not get confused by the alias name.  For production neither of these certificates should be used.  Deployments should use own certificates. However, for testing purposes be aware of these multiple key stores.

Now in OpenAM, delete the IDP and SP entities from the console and import the changes to the SAML meta-data that was changed in place on the OpenIG side.

The only difference that needs to happen to the files prior to import. but changed back before use in OpenIG, is the hosted flag that is set in both the idp-extended.xml and sp-extended.xml

Basically the copy of the meta-data that needs to be imported back into OpenAM needs to have hosted=1 for the idp-extended.xml and hosted=0 in the sp-extended.xml metadata.  Which should be exact opposite from that of the Service Provider (OpenIG).

Restart each of the web-containers after import (OpenIG and OpenAM) and try.

Once working a SAML payload should now look like this:

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="s2773fa280cdacc7e591189474f7c37a65c440f2ca" InResponseTo="s2be8aad955e0a068adb14260784005f5cb83f391a" Version="2.0" IssueInstant="2017-02-26T23:13:06Z" Destination="http://XXXXXXXXXX"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://XXXXXXXXXX</saml:Issuer><samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Value="urn:oasis:names:tc:SAML:2.0:status:Success">
</samlp:StatusCode>
</samlp:Status><saml:EncryptedAssertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><xenc:EncryptedKey><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/><xenc:CipherData><xenc:CipherValue>dnzVx9L58Kqe5vT6jX7OrIZUYgJH2L6vifmRKbZ+TBLsbFzz181yCAAyzQZu+tcLl2eqO+wzykOR
Py8AfwUx20L8KRfB4KgOb0yEq1y3Wpcyg/gIGd5GRjM0C17eNT61uOCpJ43qkTEtJanbhW7HEO7r
yml5bPZ74wYOBDK1NHY=</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>OwSwziVjZ7CntCK10iT8tFkrRoe5qy3QcEMnRhk7ipf1dgrGuQgThExmdtVohUyTdbegZs4bCCDt
6onU0ayihcDKpq3x7INOyeMh8RjYd9KTjEgh+9R+QqDisiOZMNiknxmfbV0CaDC7QaGhuqEW5zWK
jZaNMALTn42phtFhIR+Dr9yHRqjdpAeNi94EBEepypBbJhiX/5FVuwl+e6syQKSLBAoMG+jlRGKm
rQFZTcLE5+4kH5JlqTO4u/M8X56pJSOk2+O5cU1+KHYNkn4sA/1qpEP1QoL9YHvtsvtnSxSbkSbx
W2ZrzFoxKRqxVSQ0y7StX9bCRvcieUQB7kz3yVPatcTLvAZYDYBSO0aGY+Yg5kA8ishClAUxNpVx
m59NeXF3I+sZRrs2F6gpqIiQmJdsHX2VdyGNo6jSHYyBV+I+4ygfDvJQP5HkGszWkLpHX0sREaSY
xjLAENVyB6LpX/5ZfkUh6KasdjklASASDIJaljdsdnjasASDJjkdWqsRvvhwRRuo0hOs/M3mHENJ
Y3BaYZrrjaQU7u9he9cNT4q7opgSl9RZ4dEl60g6y4L/BHBxYIankw7I1v4sHCthTjaxCvUFrd4T
q6KOE2gOTvL18enrBGIxrWbm7pJWLnD3E/BsTuOPKkEOrD+WaLRPjJy8MA==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></saml:EncryptedAssertion></samlp:Response>

References
https://backstage.forgerock.com/docs/openam/13.5/dev-guide/chap-fedlets#fedlet-signing-encryption
https://backstage.forgerock.com/docs/openig/4/gateway-guide#chap-federation

This blog post was first published @ http://nin9tyni9e.blogspot.no/, included here with permission from the author.

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.

 

Blocking on Promises (Hard-learned lessons on asynchronous programming)

OpenIG is now 100% asynchronous! In other words, we’re using a lot of Promises. Recently, we faced a strange issue where a thread remained in the WAITING state, waiting for an HTTP response to come.

Here is the thread dump we got:

"I/O dispatcher 1" #13 prio=5 os_prio=31 tid=0x00007f8f930c3000 nid=0x5b03 in Object.wait() [0x000070000185d000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x000000076b155b80> (a org.forgerock.util.promise.PromiseImpl)
	at java.lang.Object.wait(Object.java:502)
	at org.forgerock.util.promise.PromiseImpl.await(PromiseImpl.java:618)
	- locked <0x000000076b155b80> (a org.forgerock.util.promise.PromiseImpl)
	at org.forgerock.util.promise.PromiseImpl.getOrThrow(PromiseImpl.java:144)

Ok, to tell the truth, the code was performing a blocking call on a Promise<Response>, so we got what we deserved, right? Well, that code has been around (in more or less the same form) for a long time, and, AFAIK, nobody had experienced a thread blockage issue.

Here is the code where the blocking call happened:

try {
  Promise<JsonValue, OAuth2ErrorException> promise = registration.getUserInfo(context, session);
  return promise.getOrThrow(); // < - - - - - - block here
} catch (OAuth2ErrorException e) {
  logger.error(...);
} catch (InterruptedException e) {
  logger.error(...);
}

Dead simple, isn’t it ?

The strangest thing happened when we engaged a timeout on the promise (using getOrThrow(10, SECONDS)). After the timeout expired, the Promise unblocked and we saw a real Response inside (with an associated SocketTimeoutException), just like if it was already there, but without the promise triggering callbacks.

How could this be possible? Having a thread waiting for a result of another HTTP request, when the http client library in use (Apache HttpAsyncClient in our case) is supposed to handle threads by itself (and correctly).

Well, we had to dig, but we found the key deep inside the HTTP library:

// Distribute new channels among the workers
final int i = Math.abs(this.currentWorker++ % this.workerCount);
this.dispatchers[i].addChannel(entry);

What is this code doing ?

This code is called when an NIO event comes back into the HTTP library (such as the content of a response). The code basically selects one of the worker threads to be responsible for processing the response.

Is this wrong ?

Depends on your point of view ;) Initially, I was thinking that it was plain wrong: this code doesn’t know if the thread is busy doing something else or blocked.

After a bit more thought, it’s not that obvious - because responses are processed asynchronously, the request and response flows are clearly decoupled, so there is no easy way to know if the requestor thread is the same thread as the response thread.

So what happened ?

The scenario is quite simple:

  • Create a CHF HttpClientHandler
  • Send the first HTTP request
  • When the response is there, trigger another HTTP call
  • See the blocked thread

In practice, you probably have to configure the number of workers, until you can find a setting where the distribution function re-assigns the response to the requestor’s thread. The easiest configuration is to use a single-thread :)

Here is a code sample to reproduce the “issue”:

// Create an HTTP Client with a single thread
Options options = Options.defaultOptions()
                         .set(AsyncHttpClientProvider.OPTION_WORKER_THREADS, 1);
HttpClientHandler client = new HttpClientHandler(options);

// Perform a first request
Promise<Response, NeverThrowsException> main;
Request first = new Request().setMethod("GET").setUri("http://forgerock.org");
main = client.handle(new RootContext(), first)
             .then(value -> {
                 // Perform a second request on the thread used to receive the response
                 try {
                     Request second = new Request().setMethod("GET")
                                                   .setUri(URI.create("http://www.apache.org"));
                     return client.handle(new RootContext(), second)
                                  // and block here
                                  .getOrThrow(5, TimeUnit.SECONDS);
                 } catch (InterruptedException e) {
                     return newInternalServerError(e);
                 } catch (TimeoutException e) {
                     return newInternalServerError(e);
                 }
             });

// Get the response on the "main" thread
Response response = main.getOrThrow();
long length = response.getHeaders().get(ContentLengthHeader.class).getLength();
System.out.printf("response size: %d bytes%n", length);

Note that you can clone the sauthieg/blocking-on-promise GitHub repository if you want to play with that code by yourself.

The solution

Avoid the blocking call and use Promise with appropriately typed callbacks in every step of the processing.

Registering callbacks (ResultHandler, Function or AsyncFunction) instead of actively waiting for a result/failure prevents any form of thread blockage.

So now, the caller thread is not blocked. It will be available for its next task after all callbacks are registered on the promise.

Bad code example

try {
  Promise<JsonValue, OAuth2ErrorException> promise = registration.getUserInfo(context, session);
  JsonValue info = promise.getOrThrow(); // < - - - - - - block here
  return new Response(Status.OK).setEntity(info);
} catch (OAuth2ErrorException e) {
  return newInternalServerError(e);
} catch (InterruptedException e) {
  logger.error(...);
}

Good code example

return registration.getUserInfo(context, session)
                   .then((info) -> {
                     // process the result when it will be available
                     return new Response(Status.OK).setEntity(info);
                   },
                   (e) -> {
                     // Convert exception
                     return newInternalServerError(e);
                   })

The conclusion

Never block any threads when you’re doing asynchronous processing.

The async programming model is designed to maximize use of machine’s resources, and implicitly requires that there are no blocking call on the stack. As there should be no threads blocked at anytime, any thread can be selected to process a response. That explains why our HTTP library is not even trying to see if the elected thread is busy or not.

More pragmatically, when using our Promise API, you’ll know that you’re in trouble (and a potential victim of that threading issue) if you see code that uses one of the get() method variations on the Promise interface.

In OpenIG, this can be in any Filter / Handler that you write by yourself, or in any Groovy script. So take a look at the code you execute in OpenIG: we make a point to write 100% asynchronous / non-blocking code, what about you?

Exhaustive list of blocking methods in Promise

  • Promise.get() / Promise.get(long, TimeUnit)
  • Promise.getOrThrow() / Promise.getOrThrow(long, TimeUnit)
  • Promise.getOrThrowUninterruptibly() / Promise.getOrThrowUninterruptibly(long, TimeUnit)

Addendum to ForgeRock Full Stack Configuration – Using ForgeRock OpenIG

This is an extension of an earlier post that demonstrated ForgeRock Full Stack Configuration, comprising OpenDJ, OpenAM and OpenIDM. In here we’ll plug in ForgeRock OpenIG to route traffic to/from OpenAM and OpenIDM. In the video log that follows, you’ll see:

– All urls that hit OpenIG, containing a string ‘openam’ getting redirected to OpenAM URL
– All urls that hit OpenIG, that does not contain the string ‘openam’ getting redirected to:

  1. OpenAM for Authentication if there is no valid User session and then on to OpenIDM UI
  2. OpenIDM UI if there is a valid User session

So here’s the extended illustration

AddendumToFullStackConfiguration

Now on to the video.Enjoy!

This blog post was first published @ www.fedji.com, included here with permission.

ForgeRock OpenIG 4 As OpenAM Policy Enforcement Point

This blog post was first published @ www.fedji.com, included here with permission.

We know of it as a job usually done by the OpenAM Web/J2EE Policy Agent to enforce a Policy Decision sent by the Access Management Solution. To help you recollect, this is how it works:

– An End User tries to access a resource (say, a URL)
– The Web/J2EE Policy Agent deployed in the Container, intercepts the requests and redirects the request to Access Management Solution
– The Access Management Solution, first Authenticates the User, does a redirection to the the Resource (URL), where Agent would again receive it
– The Agent would now ask the Access Management Solution whether the Authenticated User has access to the Protected Resource (Authorization)
– Based on the policies defined in the Access Management Solution for the Protected Resource, it constructs a Decision and sends it back to the Agent
– Whatever the decision Agent receives from the Access Management (whether to ALLOW or DENY access to the Protected Resource), the Agent Enforces it!

The story in the video below is a bit different. In fact, the protagonist is different. The honours of Enforcing a Policy Decision sent by OpenAM is on ForgeRock OpenIG 4. As for the flow, it by and large remains what is mentioned above, just that the OpenIG uses its Route Configuration file to decide whether it should redirect the Client requests to OpenAM (should the SSO Cookie is absent in the request), ask OpenAM for Policy Decisions on Protected URLs by Authenticated Users and finally to enforce a Decision that is sent by OpenAM (whether to ALLOW or DENY access to Protected URLs).

Very roughly, here’s an illustration of the flow:

To see it in action, watch the screen-cast below. Enjoy!

Related Documentation:
ForgeRock OpenIG Documentation

ForgeRock OpenIG 4 – Getting Credentials from ForgeRock OpenAM 13

This blog post was first published @ www.fedji.com, included here with permission.

Interested to see how ForgeRock Identity Gateway orchestrates with the ForgeRock Access Management solution to replay a User Credential on to a Legacy Application giving him/her access to it? There’s a screen-cast right below this write up. I had already posted a couple of entries on this space, demonstrating how OpenIG fetches User Credentials from different Datastores like a CSV file and a JDBC Database. While it’s not a prerequisite to know it before viewing the Video below, it might help get a good grip on the steps performed. So if you haven’t come across those blog entries yet, here it is:

ForgeRock OpenIG 4 – Getting Credentials from File Datastore
ForgeRock OpenIG 4 – Getting Credentials from Database

What to expect in the video?

– A user tries to access ‘http://openig.mydomain.com:8080/replay’ url
– A Java EE OpenAM Policy Agent sitting in front of the ‘http://openig.mydomain.com:8080′ url intercepts the request from the client (user’s browser) and redirects the request to ForgeRock OpenAM (http://openam.mydomain.com:8080/openam)
– ForgeRock OpenAM will send the OpenAM Login Page back to the user
– The user supplies the credential, which the OpenAM verifies. If authentication is successful,OpenAM adds the username of the user and his/her encrypted password to the session and sends it to Java EE Policy Agent
– Java EE Policy agent validates the user’s session, gives control to OpenIG.
– Because the URL that the client requested for (http://openig.mydomain.com:8080/replay), matches a specific route (say 04-route.json) configured in OpenIG, it applies the filters in the route configuration file. The first filter will use a shared key (also known to the OpenAM) to decrypt the encrypted password sent by OpenAM. The second filter will retrieve the username and password from the exchange and replaces your browser’s original HTTP GET request with an HTTP POST login request that contains the credentials to authenticate and the third filter will remove the username and password headers before continuing to process the exchange.
– The HTTP server validates the credentials and respond back to OpenIG with user’s profile page
– OpenIG sends that response to the End user

Note: OpenAM in our setup is configured to process a ‘Password Replay’ Java Class on successful authentication. The Java EE agent in OpenAM is configured only for Single Sign On (SSO) and is configured to add the UserToken (username) and sunIdentityUserPassword (password) as session attributes in HTTP header. And the FQHN of OpenAM deployment in the Video demonstration is ‘idp.mydomain.com’ and not ‘openam.mydomain.com’

To satisfy your Visual Cortex, here’s an illustration of the steps above:

OpenIG Fetching Credentials from OpenAM-Modified

Now on to the step by step configuration. Enjoy!

Related Documentation / Video:
– ForgeRock OpenIG Documentation
– Screncast on ‘ForgeRock OpenIG 3.x : Getting Credentials from OpenAM

OpenIG 4.0 is now available

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

January’s release of the ForgeRock Identity Platform includes OpenIG 4. This release brings new API gateway features, better integration with OpenAM, extended support for standards, and increased performance.

OpenIG 4’s new audit framework now handles audit events in a common way across the whole ForgeRock platform. For example, OpenIG 4 can track interactions across OpenAM, OpenDJ, and OpenIDM. Audit logs can be centralized and transactions can be traced across the platform. Additionally, the audit framework supports logging to files, databases, and the UNIX system log.

Improved monitoring data for the servers, applications, and APIs provides a better view of how OpenIG 4 and its routes are used. Delivered through REST endpoints, data includes request and response statistics, such as the number of requests, time to respond, and throughput.

The new throttling feature limits access to applications and APIs, increasing security and fairness. Throttling can enforce flexible rate limits for a variety of use cases, such as to limit the number of requests per minute from clients at the same network address.

Several new features improve integration with OpenAM:

  • A new policy enforcement filter allows only authorized access to protected resources. You can now use OpenIG instead of an OpenAM agent for authorization, and centralize all your access control policies in OpenAM.
  • SSO and federation for applications has been extended by a token transformation filter to use with the OpenAM REST Security Token Service. By using the filter, a mobile app with an OpenID Connect token can now access resources held by a federated service provider.
  • A new password replay filter simplifies the configuration for replaying credentials in common use cases.

Support for standards has been extended:

  • OpenID Connect Discovery makes it possible for users themselves, instead of system administrators, to select identity providers.
  • Initial support is available for a User Managed Access resource server, where users can control who accesses their resources, when, and under what conditions.

Behind the scenes, OpenIG 4 internals have been refactored to improve scalability – because we are no longer blocking threads, a single deployment can handle more requests at the same time.

These are just some of the changes in OpenIG 4. Check the Release Notes for a full list of what’s new in this release, and download the software from ForgeRock’s BackStage.

We love your feedback. Please feel free to ask questions, make suggestions, and tell us what you think of OpenIG by joining the community and getting on the forum and mailing list.

ForgeRock OpenIG 4 – Getting Credentials From Database

This blog post was first published @ www.fedji.com, included here with permission.

To know how ForgeRock OpenIG 4 is configured to fetch User Credentials from a Database for User Authentication (a process transparent to the User), the following Video log might help. I had posted a similar video on this space earlier, but that then the User Credentials were fetched from a Flat File (CSV). The flow isn’t quite different from that, just that a Filter used by ForgeRock OpenIG in this case is different and that we should configure the OpenIG to connect to the DB.

In the video, we’ll:
– Install the H2 Database. Create ‘Users’ table and load User data in it
– Configure OpenIG (deployed in Jetty) to connect to the Database
– Prepare OpenIG Route Configuration file to fetch User Credentials (based on a Email address) and post the data to HTTP Server, who responds with the User profile page

For those whose right side of the brain is more prominent, here’s the visual representation of what is mentioned above:

OpenIGGettingCredentialsfromDB-Updated

For those who don’t want to think too much looking at the illustration below, but would like to sit back, relax and enjoy watching a show, here’s the video. Enjoy!

Related Documentation/Video
ForgeRock OpenIG Documentation
Screencast on using OpenIG 3.x to Connect to a JDBC Datastore

OpenIG 4.0 is now available

January’s release of the ForgeRock Identity Platform includes OpenIG 4. This release brings new API gateway features, better integration with OpenAM, extended support for standards, and increased performance.

OpenIG 4’s new audit framework now handles audit events in a common way across the whole ForgeRock platform. For example, OpenIG 4 can track interactions across OpenAM, OpenDJ, and OpenIDM. Audit logs can be centralized and transactions can be traced across the platform. Additionally, the audit framework supports logging to files, databases, and the UNIX system log.

Improved monitoring data for the servers, applications, and APIs provides a better view of how OpenIG 4 and its routes are used. Delivered through REST endpoints, data includes request and response statistics, such as the number of requests, time to respond, and throughput.

The new throttling feature limits access to applications and APIs, increasing security and fairness. Throttling can enforce flexible rate limits for a variety of use cases, such as to limit the number of requests per minute from clients at the same network address.

Several new features improve integration with OpenAM:

  • A new policy enforcement filter allows only authorized access to protected resources. You can now use OpenIG instead of an OpenAM agent for authorization, and centralize all your access control policies in OpenAM.
  • SSO and federation for applications has been extended by a token transformation filter to use with the OpenAM REST Security Token Service. By using the filter, a mobile app with an OpenID Connect token can now access resources held by a federated service provider.
  • A new password replay filter simplifies the configuration for replaying credentials in common use cases.

Support for standards has been extended:

  • OpenID Connect Discovery makes it possible for users themselves, instead of system administrators, to select identity providers.
  • Initial support is available for a User Managed Access resource server, where users can control who accesses their resources, when, and under what conditions.

Behind the scenes, OpenIG 4 internals have been refactored to improve scalability - because we are no longer blocking threads, a single deployment can handle more requests at the same time.

These are just some of the changes in OpenIG 4. Check the Release Notes for a full list of what’s new in this release, and download the software from ForgeRock’s BackStage.

We love your feedback. Please feel free to ask questions, make suggestions, and tell us what you think of OpenIG by joining the community and getting on the forum and mailing list.


Note: If you happened to notice that my english has noticeably improved in this post, there is a reason :) I therefore would like to give full credits to Joanne, our new tech writer, who wrote all of this.

ForgeRock OpenIG 4 – Getting Credentials From File Datastore

This blog post was first published @ www.fedji.com, included here with permission.

If we’ve just moved ahead of ‘Getting Started with OpenIG 4‘, the following screen-cast might of some interest. In fact, this is a remake of a video that’s posted here, which was based on now older version of ForgeRock OpenIG.

So what’s in the video here? We’ve a CSV file with some User details. A user tries to access a URI, which hits OpenIG, who by using some Route Configuration files, looks up User Credentials from the CSV file and posts it to the HTTP Server, to get a User Profile Page (Post Authentication Landing Page) in return. So the Client, without having to go through the inconvenience of supplying his/her User Credentials, gets the Post Authentication Landing Page from the HTTP Server. See, if my attempt to capture the flow below makes sense.

ForgeRock OpenIG 4 - Getting Credentials from File Datastore

If that didn’t make your life easy, hopefully the demonstration in the video will. Enjoy!

Related Documentation/ Video:
ForgeRock OpenIG Documentation
ForgeRock OpenIG 3.x – Getting Credentials from File Datastore