oAuth2 One-Pager
Authorization Code Flow
-
Authorization Code Flow is the most secure authorization option but only useful when the application has a backend component like a server.
-
The client id and client secret cannot be exposed to a user in the browser or the mobile application.
-
The authorization happens through a backchannel between the identity provider and the web server.
Workflow Steps
-
The user requests to login.
-
The web application sends the user to an identity provider that both trusts.
-
The user performs the authentication by entering the username/password and grants the web application the permissions (scopes) requested.
-
The browser gets back an auth code.
-
The browser sends the auth code to the web application server.
-
The web application server sends the auth code, its client id and its client secret to the identity provider.
-
The identity provider validates the 3 inputs and if they are valid, it sends back the id token and an access token for the requested resource to the web application server.
-
The web application server then uses this access token to gain access to the resource on the user’s behalf.
Flowchart
sequenceDiagram participant U as User participant M as MvcWebApp participant I as IdentityProvider participant S as ServiceApi U->>M: Requests for access to the service activate M M->>M : Checks if user is logged in M->>I: Request for login screen deactivate M activate I I-->>U: Login Screen deactivate I U->>I: Submission of email id and password activate I I ->>I: Validate User Details I -->>M: Receives auth_code deactivate I activate M M ->>I: Sends auth_code, client_id and client_secret activate I I ->>I: Validates the inputs I -->>M: Sends access token deactivate I M ->>S: Sends access token activate S S ->>S: Checks the access token and verifies the scope S -->>M: sends response deactivate S M -->>U: User receives access to service
Benefits
-
The auth code is one time use-only.
-
The application never sees the user’s credentials.
-
The user in the browser never sees the access or refresh tokens.
Authorization Code Flow with Proof Key for Code Exchange (PKCE)
-
Authorization Code Flow with Pkce is an option in case the client cannot keep a secret like an SPA application where there is no backend server component.
Workflow Steps
-
The user navigates to the app and requests to login.
-
The client app redirects the user to an identity provider that both trust.
-
The client app generates a code_verifier which is a random url safe string of at least 43 characters.
-
Then it creates a code_challenge which is a base64 encoded SHA 256 hash of the code_verifier.
-
When the user makes the login request, the client app sends the code_challenge to the identity provider keeping the code_verifier with itself a secret.
-
Assuming the authentication was successful, the identity provider returns with the auth code to the client.
-
The client app sends the auth code and the code_verifier to the identity provider.
-
The identity provider hashes and encodes the code verifier and compares it to the code challenge sent before.
-
As the code verifier was never sent before and since the code challenge and the code verifier are sent seperately, the identity provider can safely assume that the original authorized application is the one still making the request.
-
The authorization server then sends the tokens to the application.
Flowchart
sequenceDiagram participant U as User participant C as Client Application participant I as IdentityProvider participant S as ServiceApi U->>C: Requests for access to the service activate C C->>C : Generates code_verifier and code_challenge C->>I: auth_code request and code_challenge sent to /authorize deactivate C activate I I-->>U: Login Screen deactivate I U->>I: Submission of email id and password activate I I ->>I: Validate User Details I -->>C: Receives auth_code deactivate I activate C C ->>I: Sends auth_code and code_verifier to /oauth/token activate I I ->>I: Validates the code_verifier and the code_challenge I -->>C: Sends the id_token and the access_token deactivate I C ->>S: Sends access token activate S S ->>S: Checks the access token and verifies the scope S -->>C: sends response deactivate S C -->>U: User receives access to service
Things to remember
-
No refresh tokens can be used as it cannot be kept a secret.
-
Protect your redirect_uri. This is where the identity server provider sends the auth code after authentication is complete.
-
Most identity providers ask you to whitelist redirect uri’s so that it won’t send the auth code to a random uri.
Client Credentials Flow
-
Client Credentials flow is useful when you have no user involved. For example, batch programs, windows services.
-
If these programs require access to a service, you can use the client credentials flow to authorize them.
Workflow Steps
The client sends its id and secret which is effectively its username and password to the authorization server which generates an access token and returns it to the client.
Implicit Flow
-
Use this when the client cannot keep a secret like a browser or a mobile app. However, prefer PKCE Implementation.
Workflow Steps
-
You navigate to the app and request to login.
-
The client app sends you to an identity provider or an authorization server that you both trust.
-
Once authenticated, the authorization server sends the token back to the client for use.
Things to remember
-
It is hard to secure because the token is visible in the redirect url, so an attacker might be able to use it.
-
If your authorization server supports CORS then a form post can be used to get the access token.
-
However, if the authorization server supports CORS, then just use the PKCE implementation.
Device Grant Type Flow
-
It was deviced to specifically handle internet connected devices.
-
This isnt for mobile or iot.
Workflow Steps
-
The user identifies that they want to authenticate.
-
The device calls the authorization server and identifies itself with a device id.
-
The auth server generates a device code, an end user code and a verification URI for the end user.
-
The device presents the end user with the verification URI for them to visit.
-
The user visits the URI and authenticates itself according to the requirements.
-
After authentication, the end user presents their end user code to the auth server.
-
Now their session is logically connected to the device which originated the request.
-
The device in the back end is constantly polling the auth server to determine if the user has completed the authentication.
-
Once the user is authenticated and authorized the client device, this polling retrieves the access token.
Things to remember
Requirements for Grant Type:
-
The device is already connected to the internet.
-
The device can make HTTPS requests.
-
The device can communicate a URI to the end user.
-
The user has to have a device available to use the URI.
JWT Tokens
-
JWT or JSON Web Tokens.
-
It is encoded not encrypted JSON data.
-
It includes fields like the iss(issuer), (iat)issued at, sub(subject), aud(audience), and exp(expiration).
-
Issuer is the issuer auth server.
-
iat is the issued at time.
-
sub indicates who the token is about.
-
aud indicates who should use it.
-
exp indicates the maximum time you can use or trust this token.
Id Tokens
-
The id token comes from oidc and is always a jwt token.
-
Id tokens are highly structured and defined.
-
It depends on which scopes the application requests.
-
There is the profile scope, the email scope, the address scope and the phone scope.
-
The names and structure of the scopes are highly defined and structured.
-
So it is consistent across vendor implementations.
Opaque Tokens
-
Opaque tokens mostly represent a database id.
-
It is mostly used by the authorization server which references that id to get more details about the token.
Refresh Tokens
-
A refresh token gives you a new token, once the original expires.
-
You take the refresh token back to the authorization server and request a new access token.
-
The authorization server can grant or deny that based on your permissions.
-
Refresh tokens are Opaque Tokens.
-
It means they are not JWT that we can inspect or verify.
-
It can be used only at the token endpoint of the authorization server.
-
The authorization server can take the refresh token, make sure it is active and publish a new access and refresh token.
-
It needs to be protected as an attacker can then use the refresh token to keep getting new access tokens.
-
It is maybe why a revocation api is required.
Scopes
-
A scope is a permission the client can request.
-
Its like when you check in a hotel you get permission(scope) to use your room, gym or pool.
-
When you are granted a set of scopes(permissions) you receive an access token.
-
It is like a hotel key card. You get access to your room, gym or pool with it for a set period.
-
Scope names can be any simple string.
Validating JWT tokens
-
JWT tokens generally contain the full authorization and profile data that downstream systems can use without consulting the authorization server.
-
Validating JWTs is important as that is how we establish trust.
-
Only access and id tokens are validated.
-
First you have to retrieve the keys document which represent the public key with which the token is signed with.
-
Generally these keys are available by a url from the authorization server.
-
A JWT token consists of the header, the payload and the signature.
-
They are seperated by a dot or period.
-
The base64 decoded header is a JSON document.
-
What we need here is the value of the key 'kid' short for 'the key id'.
-
Use the key to sign the payload and compare the signature with the signature in the token.
-
If they don’t match then the token has been tampered with or is not for you.
-
The decoded body of the token should be validated.
-
The iss should match the authorization server.
-
The aud should match the audience claim set in the authorization server. This confirms who the token is destined for.
-
The cid or the client id should match the client id that requested the token.
-
The exp should be in the future.
oAuth2 Endpoints
Mandatory Endpoints
-
/authorize
-
It is used to interact with the user to confirm their identity.
-
It is used for any user facing grant types such as the Authorization Code Flow or Implicit Flow.
-
-
/token
-
It is used once the user is confirmed or if there is no user at all.
-
It is used to retrieve the token.
-
The Client Credential Flow and Resource owner password will use this directly.
-
Authorization Code Flow will use this after /authorize
-
Possible Endpoints
-
/introspect
- Allows you to analyse and decode a token. -
/revoke
- Allows to invalidate an access token or a refresh token. -
/userinfo
- from the oidc spec. It publishes user profile data.
Things to remember
-
With the exception of
/userinfo
, the others can be called anything they want. -
So when you connect to an oAuth provider you need to figure out how it structures urls. It can be difficult and messy.
-
Luckily, to mitigate that struggle there is a well known endpoint.
/.wellknown/oauth-authorization-server
. -
Also known as the outh authorization server metadata document or more simply the oAuth discovery document.
-
This document lists all the url patterns for all the offered endpoints.