Up close with OAuth2 - Detailed Explanation of User / Client / Server Communication
Even though an OAuth2 secured request takes little time to complete there is a lot happening under the hood. This page will explain what messages are send between user, client and authorization server when OAuth2 "happens". For this explanation the authorization code flow serves as an example.
Figure 1 shows the authorization code flow with its many steps. Following the figure all steps are explained in detail.
Figure1:
The steps (7) and (8) are optional and belong to OpenID-Connect. They validate the access token. OAuth2 doesn't specify how to validate an access token and it could be that (9) sends the access token with the request and the protected resource validates the token. In this example we will assume that step (7) and (8) are included meaning this is an OAuth2 with OpenID-Connect scenario.
Another assumption is that all requests succeed. If they otherwise fail the server usually answers with an error response. Errors can happen when parameters are missing or parameter values are wrong.
Some fictional data is defined to make this example easier to understand. The user wants to access a protected resource. He uses his browser to do so. The client listens on www.client.de for incoming requests and acts as a proxy to the secret resource. The protected resource is behind a firewall and not directly accessible by the user. The user has to call the client to request the protected resource. The authorization server listens on www.server.de for incoming requests. All messages between the parties are send through http requests. The client is already configured for the authorization server ( e.g. through an OpenID-Discovery file ).
The user has the login credentials john and secret. The client has the client credentials cid123 and cs321 and the OAuth2 callback URL http://www.client.de/oauth2callback. The email scope is available.
1. Request for Resource
The user requests www.client.de with his browser. This is a GET request to www.client.de without any additional parameters.
2. Redirect to authorization server
The client accepts the request and answers with a redirect to http://www.server.de/auth with additional query parameters. The parameters are:
Parameter name | Value |
---|---|
client_id | cid123 |
response_type | code |
scope | |
redirect_uri | http://www.client.de/oauth2callback |
state | <an opaque value that is not to be interpreted by anyone except the client itself> |
The URL should look similar to this: http://www.server.de/auth?client_id=cid123&response_type=code&scope=email&redirect_uri=http%3A%2F%2Fwww.client.de%2Foauth2callback&state=sOmEsTaTeVaLuE. Note that values need to be URL encoded.
3.1 Authorization request
The user automatically calls http://www.server.de/auth?client_id=cid123&response_type=code&scope=email&redirect_uri=http%3A%2F%2Fwww.client.de%2Foauth2callback&state=sOmEsTaTeVaLuE as a GET request. The authorization server accepts this request and redirects the user to a log in screen. This is OAuth2-Provider specific.
3.2 User logs in
The user is presented with a log in screen. The user puts in john and secret as his credentials. A consent screen could be displayed afterwards that the user also accepts. The authorization server generates an authorization code. Assume the value of this authorization code is authcode123.
4.1 Redirect to client
After authentication is done the authorization server redirects the user to http://www.client.de/oauth2callback with additional query parameters. The parameters are:
Parameter name | Value |
---|---|
code | authcode123 |
state | <The same value that was sent by the client> |
The URL should look similar to this: http://www.client.de/oauth2callback?code=authcode123&state=sOmEsTaTeVaLuE. Note that values need to be URL encoded.
4.2 Callback with code
The user automatically calls http://www.client.de/oauth2callback?code=authcode123&state=sOmEsTaTeVaLuE as a GET request. The client accepts this request, extracts the authorization code and keeps the connection open.
5. Token request
The client sends a request to http://www.server.de/token. The request is a POST request. The following header has to be set:
- Content-Type: application/x-www-form-urlencoded
Parameter name | Value |
---|---|
code | authcode123 |
client_id | cid123 |
client_secret | cs321 |
redirect_uri | http://www.client.de/oauth2callback |
grant_type | authorization_code |
This request is accepted by the authorization server. The authorization server exchanges the authorization code for an access token. Assume the value of this access token is token123 and the token type is bearer.
6. Token answer
The authorization server responds with a JSON data structure and http status code 200. The following headers are set:
- Content-Type: application/json
- Cache-Control: no-store
- Pragma: no-cache
Field name | Value |
---|---|
access_token | token123 |
token_type | bearer |
The client accepts the response and gets the access token and token type.
7. Userinfo request
The client sends a request to http://www.server.de/userinfo. The request is a GET request. The following header is set:
- Authorization: bearer token123
The authorization server accepts the request and prepares user data corresponding to the given scope earlier.
8. Userinfo answer
The authorization server responds with status code 200 and a JSON data structure containing the user data. The content of the JSON data is scope specific.
The client accepts this response.
9. Request + 10. Response + 11. Response
A copy of the resource is fetched by the client and delivered to the users browser. The connection between browser and client is closed.