acquia / http-hmac-spec

An HMAC message format for securing RESTful web APIs.
81 stars 14 forks source link

WWW-Authenticate header #22

Open itafroma opened 8 years ago

itafroma commented 8 years ago

One thing I noticed Hawk does when attempting to access a protected resource without an Authorization header is add a WWW-Authenticate header. Something like:

WWW-Authenticate: hawk

Poking around the relevant RFCs, it turns out this is required when responding with 401 Unauthorized:

The "WWW-Authenticate" header field indicates the authentication
   scheme(s) and parameters applicable to the target resource.

     WWW-Authenticate = 1#challenge

   A server generating a 401 (Unauthorized) response MUST send a
   WWW-Authenticate header field containing at least one challenge.  A
   server MAY generate a WWW-Authenticate header field in other response
   messages to indicate that supplying credentials (or different
   credentials) might affect the response.

   A proxy forwarding a response MUST NOT modify any WWW-Authenticate
   fields in that response.

   User agents are advised to take special care in parsing the field
   value, as it might contain more than one challenge, and each
   challenge can contain a comma-separated list of authentication
   parameters.  Furthermore, the header field itself can occur multiple
   times.

   For instance:

     WWW-Authenticate: Newauth realm="apps", type=1,
                       title="Login to \"apps\"", Basic realm="simple"

   This header field contains two challenges; one for the "Newauth"
   scheme with a realm value of "apps", and two additional parameters
   "type" and "title", and another one for the "Basic" scheme with a
   realm value of "simple".

      Note: The challenge grammar production uses the list syntax as
      well.  Therefore, a sequence of comma, whitespace, and comma can
      be considered either as applying to the preceding challenge, or to
      be an empty entry in the list of challenges.  In practice, this
      ambiguity does not affect the semantics of the header field value
      and thus is harmless.

Thoughts on adding something like this to the spec?

When receiving an authenticated request, the server MUST respond with 401 (Unauthorized) and send the following header:

WWW-Authenticate: acquia-http-hmac realm="<provider>" version="<version>"

Where:

  • realm: The provider, for example "Acquia", "MyCompany", etc.
  • version: the version of this spec (i.e. 2.0)
pwolanin commented 8 years ago

So right now we just send a 403, not a 401 right?

I'm not sure a 401 and header is that useful and adds a extra complexity. It seems more geared to browser-based interactions.

itafroma commented 8 years ago

The spec currently doesn't specify the response to send if the Authorization header is not set, or if the Authorization header is invalid: I've been assuming it should be 401 in the former case, and 403 in the latter.

The WWW-Authenticate header would be useful for discoverability: it'd allow clients to determine how they should authenticate and allows servers to specify the realm and version they support without client implementors having to consult separate documentation.

pwolanin commented 8 years ago

I see the theoretical benefit, but I'm really not sure it's worth the added complexity.

As a point of comparison:

$ curl -i https://ec2.us-east-1.amazonaws.com/ec2
HTTP/1.1 401 Unauthorized
Transfer-Encoding: chunked
Date: Thu, 05 May 2016 16:06:48 GMT
Server: AmazonEC2

AWS gives you a 401 but not that header for ec2.

For IAM they just give you a 403:

$ curl -i 'https://iam.amazonaws.com/?Action=ListUsers&Version=2010-05-08'
HTTP/1.1 403 Forbidden
x-amzn-RequestId: eb45b340-12db-11e6-be45-63f0a1aa55bb
Content-Type: text/xml
Content-Length: 297
Date: Thu, 05 May 2016 16:10:43 GMT
nickveenhof commented 8 years ago

We could adjust the spec to mention the following. When returning a 401 in your application, the following MUST be adhered to:

WWW-Authenticate: acquia-http-hmac realm="" version="" Where: realm: The provider, for example "Acquia", "MyCompany", etc. version: the version of this spec (i.e. 2.0)

This could be a comma separated list if the endpoint supports multiple authentication methods. When could an application return 401? For example when credentials are not even provided. A 403 would not make a lot of sense since we were not able to check authorization yet, let alone authentication.

401 Unauthorized Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.

I can see this being very useful in the Auth Proxy, when the auth proxy could accept multiple authentication methods so depending on how it is configured, it returns a different 401 WWW-Authenticate value.

pwolanin commented 8 years ago

Making a 401 optional seems better than making it required, though we could more simply make returning the realm part of the 403 in the spec?

On Mon, May 9, 2016 at 7:38 AM, Nick Veenhof notifications@github.com wrote:

We could adjust the spec to mention the following. When returning a 401 in your application, the following MUST be adhered to:

WWW-Authenticate: acquia-http-hmac realm="" version="" Where: realm: The provider, for example "Acquia", "MyCompany", etc. version: the version of this spec (i.e. 2.0)

This could be a comma separated list if the endpoint supports multiple authentication methods. When could an application return 401? For example when credentials are not even provided. A 403 would not make a lot of sense since we were not able to check authorization yet, let alone authentication.

401 Unauthorized Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.

I can see this being very useful in the Auth Proxy, when the auth proxy could accept multiple authentication methods so depending on how it is configured, it returns a different 401 WWW-Authenticate value.

— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/acquia/http-hmac-spec/issues/22#issuecomment-217841859

Peter M. Wolanin, Ph.D. : Principal Cloud Security Engineer, Acquia. Inc.