BolkLogin

BolkLogin

You've reached the OAuth 2 authorization server for De Bolk.

Introducation to OAuth2

Read the excellent introduction to OAuth2 by DigitalOcean to understand the terminology and process involved in an OAuth 2 authorization process.

Common process for clients

The process is best described using a flow-chart: Graphical overview of the OAuth process for clients

Register your client

Log in to PHPMyAdmin on prism. Register your client in the database named "login", table "oauth_clients". You'll need to enter a client_id, client_secret and redirect_uri.

Redirect to authorization server

Direct the user in a HTML-compatible browser to

https://auth.debolk.nl/authenticate?response_type=code&client_id=example&redirect_uri=http://example.org&state=123456

with the details of your application added. The state parameter must be randomly generated. The authorization server will ask the client to log in and confirm that he/she will allow your application access to his/her account.

If the user agrees, the authorization server will redirect the browser back to your application (redirect_uri) with a "code" and a "state" parameter:

http://example.org/?code=2a134b08d15a90e5901f24a98a129&state=123456

The code parameter is your authorization token. It is valid for only a few seconds. You must trade it in for an access token in step 2.

If the user disapproves, the authorization server will redirect back to your application too, but with a "error" and "error_description" parameter explaining the cause, for example: http://example.org?error=access_denied&error_description=The+user+denied+access+to+your+application&state=1.

You must validate that the returned state parameter is identical to your original parameter. If it is not, warn your user and restart the process, otherwise you are at risk of CSRF-attacks (and the authorization token you received probably won't work anyway).

Exchange authentication token for an access token

If the user approved your application to access his/her account, you must send a POST-request to the authorization server at the address:

https://client_id:client_secret@login.i.bolkhuis.nl/token (replacing client_id and client_secret with your values)

with the following data encoded as JSON. Be sure to add a correct Content-type: application/json header.

{ "grant_type":"authorization_code", "redirect_uri":"http://example.org/", "code":"example-authorization-token" }

Alternatively, you may also use the endpoint https://login.i.bolkhuis.nl/token and supply all parameters in valid JSON:

{ "grant_type":"authorization_code", "redirect_uri":"http://example.org/", "code":"example-authorization-token", "client_id": "", "client_secret": "" }

The response of the request will contain an access token which you can use to access resources on behalf of the user. The access token looks like the following:

{ "access_token": "fb028dac33e168c60d6558a610cbbaf289f02871", "expires_in": 3600, "token_type": "bearer", "scope": null, "refresh_token": "cfa09ad5ab1c9418c6541c7726360d7b06c47e9b" }

If your request fails for some reason, the server will return an error and an error description, like this:

{ "error": "invalid_request", "error_description": "The grant type was not specified in the request" }

Validate access token

You do this by calling the authorization server at the following url:

https://login.i.bolkhuis.nl/resource/?access_token=example

If valid, the authorization server will return the full access token, the ID of the user (which you can use to look up the user details in blip and operculum) and the expiry time of the access token (ISO 8601-formatted), which looks like this:

{"access_token":"example","user_id":"jakob","expires":"2014-09-29T22:37:09+00:00"}

If invalid, you should return a 403 Unauthorized header and pass along any error codes from the authorization server to the client in the body. Otherwise you may grant access to the user.

Refresh token

Please do not refresh already fresh tokens to reduce server load. Calculate and store the expected expiry time of your access token, minus 50 seconds or so to accomodate for clock drift, and refresh the token only when needed.

Using your refresh token, issue a JSON-encoded HTTP request to:

https://auth.debolk.nl/token/

using the payload:

{ "grant_type": "refresh_token", "refresh_token": "", "client_id": "", "client_secret": "" }

If succesful, this will return a full new access token (see above for specification) and a full new refresh token. You can and should instantly overwrite your entire currently stored token with the new data. Be sure to update the expected expiry time of your token, if needed.

Send request to resource server

Using your access token, you may make requests to a resource server on behalf of the user. How to send the access token is dependent on the resource server, but the consensus is to simply append it to an URL, for example:

http://musicbrainz.i.bolkhuis.nl/player/mjs/mp3soos?access_token=example

The server will verify that your access token is valid and (if it is) execute your request.

Common process for resource servers

The process is best described using a flow-chart: Graphical overview of the OAuth process for resource servers

Receive request with access token

This is dependent on your server, though the accepted default is to simply append it to the URL:

http://server.nl/resource/?access_token=TOKEN

Validate access token

As a resource server, you need to validate access tokens sent to you by clients. You do this by calling the authorization server at the following url:

https://login.i.bolkhuis.nl/resource/?access_token=example

If valid, the authorization server will return the full access token, the ID of the user (which you can use to look up the user details in blip and operculum) and the expiry time of the access token (ISO 8601-formatted), which looks like this:

{"access_token":"example","user_id":"jakob","expires":"2014-09-29T22:37:09+00:00"}

If invalid, you should return a 403 Unauthorized header and pass along any error codes from the authorization server to the client in the body. Otherwise you may grant access to the user.

Check access level

If the access token checks out, you may grant access on behalf of the specified user. Alternatively, you may check if the user has a specific authorization level. Five authorization levels currently exist:

Additionally, there is a group in LDAP named 'oauth-test' which is normally empty. Adding a user to this group will grant all authorization levels, allowing for testing oauth security. Do not add users to this group permanently.

You can check whether the current user can access the authorization level "ictcom" for example by requesting the URL:

https://login.i.bolkhuis.nl/ictcom/?access_token=example-access-token

and checking whether the HTTP status code of the response is 200 OK.

Client credentials grant

It is possible for clients to request an access token based solely on their own existence, not an actual user account. These tokens, while valid, have the lowest possible privileges and are only used in very specific scenarios. A proper example is the door lock: the door reads a pass ID through NFC and sends it to the passmanagement API. The Passmanagement API than answers whether the door should grant access. This API call is secured over OAuth, but the door has no user input apart from the pass and therefore cannot allow users to login. The door lock uses a client credentials flow to request an access token, and signs its request to the API with this token. The client credentials grant is in accordance with the OAuth 2 RFC: https://tools.ietf.org/html/rfc6749#section-4.4.

To execute a client credentials grant, send a POST request to

https://auth.debolk.nl/token

with the correct Content-Type: application/json header and the following body:

{ "grant_type": "client_credentials", "client_id": "", "client_secret": "" }

If approved, the authorization server will return a valid access token:

{ "access_token":"", "expires_in":3600, "token_type":"Bearer", "scope":null }