in Uncategorized

Asserting Identity

Suppose that a front-end server (“A”) is sending an HTTP request to another server (“B”) to process the request and return some response, and that B needs to know on whose behalf A is making that request. This is an “identity assertion” problem. Though this problem is quite common in the HTTP/REST/API-era, the solution is still DIY. Here are some ways to support this.

  • Pass whatever token that A received from its clients (such as browsers) to B.

For instance, if A is using a Cookie (which may contain an encrypted version of the user’s identifier) as an authentication token, then A could send the same token to B.

# Browser making a request to A
GET /some-page HTTP/1.1
Host: www.example.org
Cookie: xyz

# A making a request to B
GET /some-resource?some-path HTTP/1.1
Host: some-internal.example.org
Cookie: xyz

This is fairly simple to implement as long as A can entrust B with a user’s authentication token and that the transport is secure either at the network level or physically so that cookies are not leaked to others. Another downside is that this approach couples B to A’s authentication mechanism.

  • Use basic authentication.

This is a bad idea since it requires A to store user credentials in plain text or in an encrypted form.

  • Use OAuth 1.0 style Authorization header to assert user identity.

This requires a custom HTTP authorization scheme to pass the user’s identifier along with a signature.

# A making a request to B
GET /some-resource?some-path HTTP/1.1
Host: some-internal.example.org
Authorization: MyIdentityAssertion client_id="client001",
               assertion="joe001",
               signature="xyz"
               signature_method="HMAC-SHA1",
               timestamp="...",
               nonce="..."

where client_id is an identifier assigned to A by B, assertion is the user’s identifier, and signature is a signature using a secret shared between A and B. This approach is similar to the so-called two-legged OAuth. In the OAuth case, the oauth_token – equivalent to the signature above – contains a signature of the Signature Base String where as in the above, it is just the user’s identifier.

This approach is as easy to implement, and keeps B independent of A’s authentication scheme.

  • Use TLS in stead of signatures as in OAuth 2.0

This is similar to the previous approach but without the signature, and using TLS.

# A making a request to B
GET /some-resource?some-path HTTP/1.1
Host: some-internal.example.org
Authorization: MyIdentityAssertion joe001

All these approaches leave it up to B whether to trust the assertion passed by A, and that’s what
assertions are about.

Write a Comment

Comment

  1. Is there a requirement to use the Authorization header for this kind of identity assertion? I prefer to use it for Authentication of the actual client making the request, i.e. auth’ing A to B.

    A while back I designed something similar to this that, instead of using the Authorization header, added another header to the request from A to B that just links to a URI identifying the original client, e.g:

    X-Origin-Client: “https://example.com/users/fred”

    Of course that might be better suited to the link header now, i.e:

    Link: https://example.com/users/fred;rel=originClient

    Thoughts?

    Cheers,
    Mike

    • @Mike – the protocol aspects are clear in RFC-2617. The Authorization header is meant for carrying credentials, and what is encoded in there depends on the scheme. Some schemes may incorporate typical authorization controls (like permissions) – and OAuth2 is a great example as the OAuth’s access token encompasses scopes.

    • @Dan – certainly, with the last option. Mutual auth with TLS can be used at the transport level to mutually authenticate A and B, with the Authorization header in the protocol (HTTP) used for carrying credentials/identifiers of the user.