Bearer token in authorization header vs query parameter

22,357 views
Skip to first unread message

Matt

unread,
Apr 18, 2012, 3:21:34 PM4/18/12
to API Craft
What's the best way (when desigining a REST API) to accept a access
token.

1) As an authorization header. Appears to be the preference of
Microsoft and plenty of standards (like SCIM)
2) As a query parameter. This is the approach taken by Facebook,
Google and others.

We've thought of a few arguments for (and against) each approach.
Would appreciate any insight this group might offer. Thanks.

Constantin Tovisi

unread,
Apr 18, 2012, 3:26:51 PM4/18/12
to api-...@googlegroups.com
Hi Matt

It is harder to have a custom request header set when consuming the API from JavaScript so, if this is necessary, then this is a plus for going with the second option.
-- 
Constantin Tovisi

Daniel Roop

unread,
Apr 18, 2012, 7:19:35 PM4/18/12
to api-...@googlegroups.com

Author header because it is the space reserved for it in the spec and where network caches will look for that information when considering caching.

I do believe there is the idea of accepting bothc. I think oauth allows this.

Arlo Belshee

unread,
Apr 19, 2012, 11:27:00 AM4/19/12
to api-...@googlegroups.com

We argue over this general problem a lot internally.

 

Following the HTTP spec (and the good reasons behind that guidance), clearly the right place for this sort of thing is in the headers. Query string is for stuff related to the query. Stuff related to the transaction or the communication (such as auth) goes in headers.

 

Only one problem: JSONP. Browsers’ behavior for cross-site data access from JS means that people had to hack a solution. That hack has become the norm and is JSONP. But there’s one thing the hack fundamentally cannot do: send a header.

 

There are more advanced (read complicated) workarounds for the browsers’ security “feature” and some of them allow headers. But many JS libraries don’t support these methods.

 

Thus, you are forced to choose between following the standard (put in headers) or doing what will work for everyone (put in query string or path). Some people go each way.

 

Arlo

Matt

unread,
Apr 19, 2012, 1:39:12 PM4/19/12
to API Craft
Our discussions ended with the proposal that we support both... since
our audience may invoke from "client-side" javascript and also from
"server-side" code (were the authorization header could be set).
Remaining discussion item is.... If we support both, what do we do if
some idiot API caller uses both. Error? Take the value of the to
authorization header and ignore query string? Take the value of the
query string and ignore the authorization header?

Arlo Belshee

unread,
Apr 19, 2012, 1:54:20 PM4/19/12
to api-...@googlegroups.com
That's certainly one of the problems with supporting both.

You can choose either of two of your proposed recovery options, but the third will get you into trouble.

Don't trust the query string over the header. This will break when someone grabs a URL from a dumb client and then, without understanding it, hands it to a smart client. The smart client won't think to look for and strip out the query string - it'll just send headers like it normally does. And stuff will break.

The reverse won't happen, because users pass around URLs, not full requests (with headers).

So feel free to treat "both" as an error or to prefer the header value. Just don't trust the query string if there is more reliable information available.

Arlo

-----Original Message-----
From: api-...@googlegroups.com [mailto:api-...@googlegroups.com] On Behalf Of Matt
Sent: Thursday, April 19, 2012 10:39 AM
To: API Craft
Subject: Re: Bearer token in authorization header vs query parameter

Jack Repenning

unread,
Apr 19, 2012, 2:00:26 PM4/19/12
to api-...@googlegroups.com
On Apr 19, 2012, at 10:39 AM, Matt wrote:

> Take the value of the to
> authorization header and ignore query string? Take the value of the
> query string and ignore the authorization header?

I vote "take the value that's easiest, say the one automatically snarfed by your framework; figure out which that is by experiment; document it as a 'precedence'."

Jack Repenning

I keep all my clocks set 24 hours ahead, to give myself a little extra time.

Greg Brail

unread,
Apr 19, 2012, 4:01:08 PM4/19/12
to api-...@googlegroups.com
FWIW the OAuth 2.0 bearer token spec says that servers MUST support the Authorization header and MAY support the query param. That means that if you support the query param, then you must support the header too. What to do if you see both? Good question...

The spec also strongly discourages using the query param:

   Because of the security weaknesses associated with the URI method
   (see Section 5), including the high likelihood that the URL
   containing the access token will be logged, it SHOULD NOT be used
   unless it is impossible to transport the access token in the
   "Authorization" request header field or the HTTP request entity-body.
   Resource servers MAY support this method.

and again in the "security considerations" section at the end...

   Don't pass bearer tokens in page URLs:  Bearer tokens SHOULD NOT be
      passed in page URLs (for example as query string parameters).
      Instead, bearer tokens SHOULD be passed in HTTP message headers or
      message bodies for which confidentiality measures are taken.
      Browsers, web servers, and other software may not adequately
      secure URLs in the browser history, web server logs, and other
      data structures.  If bearer tokens are passed in page URLs,
      attackers might be able to steal them from the history data, logs,
      or other unsecured locations.
--
Gregory Brail  |  Technology  |  Apigee

sune jakobsson

unread,
Apr 20, 2012, 2:21:24 AM4/20/12
to api-...@googlegroups.com
MUST overrides MAY, and hence the Authorization header wins. In OMA they have introduced "acr:Authorize" in the  
query parameter to indicate that the authorization is in the header.

Sune

Matthew Bishop

unread,
Apr 20, 2012, 12:10:40 PM4/20/12
to API Craft
Prefer header.

Liem

unread,
Apr 21, 2012, 7:53:17 PM4/21/12
to API Craft
Prefer header for better security (especially used with SSL).

Matt

unread,
Apr 23, 2012, 6:37:35 PM4/23/12
to API Craft
I agree. Prefer Authorization header. However, if you also support:
Form-Encoded Body Parameter or URI Query Parameter it's worth noting
that http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-18#section-2
also states:

"Clients MUST NOT use more than one method to transmit the token in
each request."

The draft does not give any instruction (precedence or error) for how
a service should behave if multiple methods are used by a client.

IMO, a well written service would return an error 400 Bad Request with
message-body that helps the caller know that they MUST NOT use more
than one method to transmit the authentication token. Returning an
error has the advantage of completely eliminating ambiguity about
precedence, and would help caller identify what they would probably
admin is a "bug". Yes, returning an error does requires a little more
effort on the part of the developer implementing the service, but it's
probably worth it...

--
Matt

On Apr 19, 2:01 pm, Greg Brail <g...@apigee.com> wrote:
> FWIW the OAuth 2.0 bearer token spec says that servers MUST support the
> Authorization header and MAY support the query param. That means that if
> you support the query param, then you must support the header too. What to
> do if you see both? Good question...
>
> The spec also strongly discourages using the query param:
>
>    Because of the security weaknesses associated with the URI method
>    (see Section 5
> <http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-18#section-5>),

Matt

unread,
Apr 23, 2012, 6:58:02 PM4/23/12
to API Craft
Guess... should have read the entire draft before posting:

http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-18#section-3
says:

3.1. Error Codes

When a request fails, the resource server responds using the
appropriate HTTP status code (typically, 400, 401, 403, or 405),
and
includes one of the following error codes in the response:

invalid_request
The request is missing a required parameter, includes an
unsupported parameter or parameter value, repeats the same
parameter, ===>uses more than one method for including an
access
token<===, or is otherwise malformed. The resource server
SHOULD
respond with the HTTP 400 (Bad Request) status code.

[emphases added] clears it up for me.... Return a 400.


On Apr 23, 4:37 pm, Matt <m...@implbits.com> wrote:
> I agree.  Prefer Authorization header.  However, if you also support:
> Form-Encoded Body Parameter or URI Query Parameter it's worth noting
> thathttp://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-18#section-2
Reply all
Reply to author
Forward
0 new messages