Showing posts with label openam. Show all posts
Showing posts with label openam. Show all posts

Friday, 5 May 2017

Uniform Service Authentication and Authorisation

The problem with using short-lived access tokens to enable authentication and authorisation of service requests, is that they only really work for synchronous interactions which themselves are short-lived.  Access tokens in, potentially long-lived, asynchronous messages run the risk of expiring.

An interesting alternative is to use certificates to sign (and optionally encrypt) messages.  For example, service A sends a message via some number of queues to service B.  Service A has a private certificate which it uses to sign the message.  Service B receives the message, and uses the corresponding public certificate to validate the message signature, and since this would only work with Service A's public key, service B knows the message originated from service A, and can authorise the request accordingly.    This would work equally well for synchronous calls.

Of course, this means a lot of certificates deployed to a lot of places, but certificates could be obtained from a central service, and access control applied.

So service identity is sorted, but would about user identity?

I suggest that users and core services need to be separated by a gateway layer (application or service), which would be responsible for establishing user identity via some means (basic auth, OAuth, Kerberos, or whatever), and then sending a signed user identity assertion (along with any roles it might have) along with requests and messages, much like is done in SAML.  Downstream services would trust the gateway to appropriately establish this identity, and trust would be ensured by means of the above certificate mechanism.


If you're looking for an identity & access management system, then check out OpenAM.  ForgeRock are doing an excellent job of supporting it, and the major releases are open sourced and free to use. We use it at IG for SAML, OAuth, Windows SSO (Kerberos), LDAP authentication amongst other things.  It is very easy to configure, either manually or scripted (e.g. via Puppet), and provides us a resilient, scaleable, standard authentication capability.  It does also provide policy based access management, but we've not ventured there yet.

And there it is.

Share:

Evil Session Tokens

So we build a new web application, SIMPLES.COM.  Clients login, over HTTPS of course, and a session token is issued.  Since we don't want the client to have to log in frequently, we give the token a long lifetime, or at least a way of using it to get a new one.

The application will have to persist the token on the browser, so cookies are used.  We consider using browser local storage, but cookies seemed the best way to guarantee wide browser compatibility.

The application then validates every HTTP operation, using the session token in the cookie, and authorises access as appropriate.

Sorted.

Enter the hacker.

Client Joe Bloggs receives an email with a phishing link to dodgy website S1MPLES.COM (note the name is different), and clicks on it.  Joe is taken to a page where a few sneaky GET requests are sent to the real SIMPLES.COM website, and Joe's browser helpfully supplies the session cookie, since it's the correct domain, and the hacker now has access to Joe's data.

How do we fix this?

The first thing to do is not use cookies for authentication.  The web app must attach a session token header to each request.  That way the above Cross-site Request Forgery attack is not possible.

However, we now have a long-lived session token being passed around, but that's OK, because we use HTTPS.

Except we don't.  Not all the time.

SIMPLES.COM is accessible over HTTP.  Only the login page and secure site are via HTTPS.

So Joe, being a lover of coffee, and free WiFi, gets caught by a man-in-the-middle attack by Mr Evil with a portable WiFi router.  Mr Evil intercepts the requests, and the session session token sent with each request.

Mr Evil now has full access to Joe's account, for a long time.

The answer is to make SIMPLES.COM full HTTPS, and to use HSTS to ensure no opportunity for man-in-the-middle exists. And to add all the recommended security headers, e.g. content security policy.

Cool.  Mr Evil shrugs, and picks on someone else.

Much later, Mr Bored Developer is browsing through the application logs (helpfully made available via a log aggregator), when he notices that the session tokens are logged for all to see.

Not so cool.

So what do we do?

One way is to use an OAuth approach to issue not one session token, but two: a short-lived access token, and a long-lived refresh token.  The refresh token is stored in the application browser,  but is never used for access, only to request new access tokens.

Of course these access tokens could still be leaked, but being short-lived, should expire very quickly.

Much better.

P.S. Please, please don't build your own security solutions!  Spring Security and mature open source identity and access management systems such as OpenAM are a much better way to go.

Share: