Levels of Access Control through Keycloak Part 2: Token Flows

Photo by Pixabay from Pexels

This is part 2 of a 4-part series on Keycloak. For part 1, click here, and for part 3, click here

In the previous section, we utilized curl to perform HTTP requests to get the token. This was possible through something called a Direct Access Grant and usually, in a web application or a service, we don't want that since this involves sending plaintext username and password in a request.

The most recommended way of getting a token for your application or service is through something called Authorization Code Flow.

Authorization Code Flow

First, you need to fire up the Keycloak Administration Console again and change some configuration parameters on the client we created:

  1. Disable Direct Access Grant
  2. Change the Access Type to confidential
  3. For Valid Redirect URIs specify the URL of the REST API we've implemented so far with a new path that we're going to implement now
Set client to confidential and disable Direct Access Grant
Specify a redirect URL

Click on save. Once this is done, a new tab appears on the client called Credentials. Click on it and copy the value of Secret.

Save the Secret somewhere

The Client Id and the Client Secret are a pair of credentials that an app or a service can use to authenticate itself. A client entity itself is a specification representing an app or a service wishing to utilize the authentication capabilities exposed by Keycloak.

Once this configuration is done, a token can be generated by opening this URL in the browser:

This is a URL for Keycloak with some query parameters defining what type of engagement we’re about the begin. When you open this URL, you’ll be redirected to a login page. Put in the credentials that we’ve used so far and log in. Once you’ve logged in, you’re redirected to a non-existent URL. This is fine, we’re going to build the API on this URL later on. For now, focus on the URL itself which should be of the following form:

Notice the value of code query parameter. Copy it. We now need to perform a POST request using curl with this code and the client credentials we set up earlier as follows:

In response, you’d get the same payload as before with access_token in it.

Okay, so what just happened? The exchange of requests above is supposed to be done by your app or service in an automated way as follows:

The sequential workflow of Authorization Code flow
  1. You open a browser and perform a GET call to your service
  2. Your service redirects your browser to Keycloak so that it can get an authorization code. Your browser then performs a GET on Keycloak
  3. Keycloak establishes that you’re not logged in and returns a login page
  4. Once you log in, Keycloak redirects your browser back to the service with authorization code. Your browser performs a new GET call on your service with the authorization code
  5. Combining the authorization code with client credentials, your service performs a POST call. This establishes the identity of your service and returns an access token

This is the standard OAuth2 Authorization Code Flow which a lot of modern apps and services use for different purposes. For example, wherever you see the button Login with Google or Login with Facebook, you're essentially using this flow where Google and Facebook are acting as the servers that provide authorization services like Keycloak.

To programmatically demonstrate this, let’s modify our REST API to cater for redirection as follows:

Pasting this code in a file and running it will expose this endpoint on http://localhost:1234/v1/self. Open this URL in a browser. You’ll instantly be redirected to a login page on Keycloak. Once you log in, you’d be redirected back to the REST API which would accept your request now.

Refresh Token Flow

As I specified before, tokens come with an expiration date after which they’re not valid, so if a token expires, you’d have to get a new token. Getting a new token through Authorization Code flow is disruptive in the sense that it requires a number of redirects through the browser and occasionally, it would require a user action i.e. it would want the user to log-in again on Keycloak because Keycloak’s login session also expires.

To avoid disruption, the payload that contains the access_token also comes with another token which is specified against refresh_token. Usually, the expiration of arefresh_token is more than that of access_token, so even if an access_token expires, refresh_token might still be valid.

We can use the refresh token to generate a new access token by doing the a POST request. Copy the value of refresh_token and do the POST using the curl as follows:

Programatically, you’d need to change the SelfApi handler as follows:

The recommended approach for getting tokens for your app is the Authorization Code flow which I hope you’re able to understand in detail through this story. In the next part, we’re going to bring in roles assigned to users, and use them to have access control through tokens. You can check it out by clicking here.

Code Mechanic and Deployment Plumber, Curious for Details

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store