Skip to content
Domain Specific Language

Authentication & authorization - what gives?

In which I discuss the basics of authentication, authorization, and OpenID Connect. Why?

Disclaimer: The below blog post was written by me for me, and might (and probably does!) contain errors. Don't rely on anything below as fact, from now you're on your own.

What we have

This is typically what you see when you visit pages attempting to explain authentication & authorization:

The above image specifically covers the Google OAuth 2.0 flow, using Google as an OpenID Connect Provider. This truly is the future, right? Right? Right.

Another way of describing the flow is from the OAuth 2.0 spec:

+--------+                               +---------------+
|        |--(A)- Authorization Request ->|   Resource    |
|        |<-(B)-- Authorization Grant ---|     Owner     |
|        |                               +---------------+
|        |                               +---------------+
|        |--(C)-- Authorization Grant -->| Authorization |
| Client |<-(D)----- Access Token -------|     Server    |
|        |                               +---------------+
|        |                               +---------------+
|        |--(E)----- Access Token ------>|    Resource   |
|        |<-(F)--- Protected Resource ---|     Server    |
+--------+                               +---------------+

The images leave a lot to the imagination, but on a high level they show authentication and authorization information being exchanged.

We need to know more about all the moving parts!

Authentication

OpenID Connect

One way of authenticating is using OpenID Connect, it's the third generation of OpenID - the first two being OpenID Authentication 1.X, and OpenID Authentication 2.0.

The two old versions are specific schemes for authenticating users, but were "unnecessarily complicated". Since everyone is using OAuth 2, OpenID Connect was implemented to run on top of it - or as the introduction to the spec states:

... a simple identity layer on top of the OAuth 2.0 protocol

A full list of OpenID specifications can be found on their Specifications & Developer Information site. The OpenID Connect Core 1.0 specification for example.

OpenID Connect is used by a lot of organizations, which lend their authentication service powers (called OpenID Provider - OP) to our servers (called Relying Party - RP).

Honest question: Why couldn't they just have called it OpenID 3.0 for OAuth 2.0 or something? When running across "OpenID 2.0" and then something called "OpenID Connect", naturally you're going to think that the "2.0" is newer harder better faster stronger.

Other ways

OpenID Connect is not the only game in town, Facebook Connect is another major player.

You can also try to roll your own authentication service, and if you do that you're not necessarily constrained to the requirements of OpenID Connect. It's not a bad idea to be heavily inspired by the work of geniuses, though.

Authorization

Let's talk about OAuth 2.0 baby. Let's talk about you and me. Let's talk about all the good things, and the bad things.

Instead of using the terms OpenID Provider and Relying Party, the OAuth 2.0 spec uses

Resource owner Capable of granting access, sometimes an end-user
Resource server Has resources accessible after presenting an access token
Client An application (server) making requests on behalf of the resource owner
Authorization server Issues tokens after authentication and authorization

It goes on stating "The interaction between the authorization server and resource server is beyond the scope of this specification. The authorization server may be the same server as the resource server or a separate entity.""

Authorization grant

An authorization grant is the "... resource owner's authorization (to access its protected resources) used by the client to obtain an access token"

There are four grants types defined in the spec

Each grant has an associated Flow, which are ways of obtaining tokens used for authorization after authenticating a user, the most common being authorization code flow, and implicit flow.

Authorization code flow

Typically involves a browser (user agent), a web server (client), a resource owner (user), and an authorization server.

Explained in detail in section 4.1 of the spec, summarized below:

  1. The client (server) redirects the UA to the authorization server.
  2. The authorization server authenticates the user and asks the user to grant access.
  3. If access is granted the authorization server redirects the user back to the client (server).
  4. The client (server) requests an access token using the authorization code received in step 3, the redirection URI is also sent to the authorization server for validation.
  5. The client is authenticated on the authorization server using the authorization code and redirect URI. If valid, the authorization gives the client an access token (and optionally a refresh token).

Summarized means that a lot of detail was left out. Read the spec!

In this flow, the access token never leaves the client (server), instead the client is connected to the UA/user via e.g. sessions.

I guess the access token can be exposed to the UA anyway, if the implementation chooses to do that. The takeaway is that the client uses credentials (typically client secret) issued by the authorization server, that should NOT be used in the implicit flow. Otherwise it wouldn't be a secret.

Implicit flow

Used when there is no, or you don't specifically have a need for, the client being involved. The authorization server sends an access token directly to the UA in the redirect. Typically used by Javascript clients or Android apps.

Mixin' it up

OpenID Connect runs on top of OAuth 2.0 - always keep that in mind when reading about these two separate specifications!

The concepts of the different specs and auxiliary technologies like JWT are often presented as one and the same by third parties (blogs, etc) and one needs to keep that in mind.

OpenID Connect gives you the convenient ID Token, which can be used in parallel with the OAuth 2.0 Access Token, or separately!

Tokens

All of these are (usually) JWTs. Basically they contain claims, and (AFAIK) those claims should only ever be trusted if they are digitally signed by the issuer using e.g. JWS, and that signature should always be verified by anyone about to trust those claims (e.g. a resource server).

Here's one place to play around with JWTs and different types of signatures.

JWT signatures

According to auth0 the most common types of signatures are

ID Token

The OpenID Connect Core 1.0 specification defines the ID Token in section 2.

There are a bunch of fields, and following the spec for validating the ID Token is a really good idea. Read the spec. Live the spec.

The ID Token contains claims and typically identifies a user in the context of the OP.

If you are building a service with e.g. Google Sign-In, the ID Token is issued by Google and according to them the RP should use the ID Token to uniquely identify a user in the RPs context (after verifying the integrity of the token).

If you are building your own service and don't have any use for e.g. Google APIs but you still want to use Google accounts for signing in to your service, just use the ID Token and forget about the Access Token.

Access token

"Access tokens are credentials used to access protected resources. An access token is a string representing an authorization issued to the client."

Typically, the access token is a JWT token, but according to the spec it doesn't have to be.

The most important thing is, when you need access to an API (resource), use the token that the authorization server gave you!

Access Token Types

There are a number of access token types.

Bearer token

Whoever presents the token shall be granted access to a resource as long as the token is valid. This is the most common type of access token.

MAC token

The draft still isn't finalized, but from what I can gather, the token contains some cryptographic content that would make it harder to forge and/or read. A probable use case would be using it in use-cases lacking HTTPS/TLS capabilities.

Don't quote me on that.

Refresh token

A token used to request new access tokens as they expire. Handy if one wants to avoid going through the authorization flow once again.

Other Sources