What Does The ‘Authorization: Bearer xxx-yyy-zzz’ Header Mean?
That’s right, it’s something to do with OAuth2.0!
Audience
In this article we will explain the usage of the Authorization: Bearer xxx-yyy-zzz
style header. I feel it’s one of those things that you might use a fair bit without perhaps fully understanding the implications.
This article is a crash course in understanding where it comes from, how it works and when to use it. It is based on the RFC here, which you can read for full technical details.
It expects an understanding of HTTP and OAuth2.0. Although I will offer a brief overview of the latter, I would recommend reading my introductory article here.
Argument
The Basics
OAuth2.0 is about authorisation, not authentication. That is, it cares about what we can do, not who we are.
The core of OAuth2.0 is that there is a resource server which holds resources we want. We need a key we can present to a resource server that it can check is valid in order to give us access.
The way we represent this key is using an access token. This access token contains all of the information on what we can do (but not who we are). It’s exactly like a door key — it doesn’t matter who has it, as long as it fits the lock we’re allowed in!
Access to our resource server is done using HTTP. The Authorization: Bearer
header is used to send this key along with our request to the resource server.
This is an example of an HTTP Authentication Scheme. Other examples could be basic, which would use an Authorization: Basic
header.
The bearer bit is key (pun intended). Anyone who has (bears) the token can use it, therefore we need to take care to keep it securely!
Note, how to get an access token is covered in the article here, with more details in the list of articles here, and is beyond the scope of this piece. For this article just assume we have one.
The Implementation
Now we understand conceptually, let’s look at what this means in reality.
The first important thing is we must use TLS. A typical request to a resource server for a protected resource would then look something like:
GET /protected-resource HTTP/1.1
Host: resourceserver.example.com
Authorization: Bearer access_token
In short, we send an authorization header with value Bearer
, a space, then the access token.
If we’re making a POST
request we could also send the access token in the method body, using the below syntax:
POST /protected-resource HTTP/1.1
Host: resourceserver.example.com
Content-Type: application/x-www-form-urlencoded
access_token=access_token_value
And finally we can also use the query params to specify the token:
https://server.example.com/resource?access_token=access_token_value
We can see why it’s so important to use TLS. By doing this we guarantee that each of the above is encrypted, and only the resource server can read our access token.
So far, so good. We’re defining a way of sending over a token. However, what happens when we forget or it isn’t valid? We need a server error response!
Let’s say we’ve got an access token, but it doesn’t have the right scopes (i.e. we have some permissions, but not for the resource we’re asking for). In this case we’ve not got access to The Beatles’ explicit tracks.
Then we may get a response similar to the below:
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer realm="examplerealm",
error="insufficient_scope",
scope="urn:example:artist=TheBeatles&urn:example:age=O18"
error_description="Cannot access tracks!"
We see we return a sensible error code, then use the WWW-Authenticate
header to prompt for authentication.
We specify the HTTP Authentication scheme (bearer), then at least one other auth-param
value. These can include:
- The realm: If we have multiple resources on a resource server, each of which need their own different types of protection we may separate them into ‘realms’. This allows us to group them according to their protection needs.
- The scope: This is a list of scopes that are required to access the resource.
- The error: one of the linked values explaining what the issue was.
- The error_description: A human readable error message that can be displayed to end users.
- The error_uri: A link to a human web page explaining the error.
With all of this information, it is then the responsibility of the user to go away and get the required access token!
Conclusion
And there you have it! What that header means, how we use it, and how we deal with responses!