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
Authorizationheader 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="..."
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.