Authentication is hard: Keycloak to the rescue
Tags: docker, flask, keycloak, sso
Published: 2019-05-14 19:17:46

---
title: Authentication is hard: Keycloak to the rescue
published: true
tags: docker,flask,keycloak,sso
canonical_url: https://medium.com/@agusnavce/authentication-is-hard-keycloak-to-the-rescue-32ca4b442a13
---

Many times when we start developing a software solution the need for security arises. We want to mantain secure and private every part of our app.

As developers, most of the time we are bound to implement each system individually by our selves. It gets tedious to keep having to create authentication modes. It takes a lot of work…

Here is where Keycloak enters in the scene. Keycloak is an open source identity and access management to add authentication to applications and secure services with minimum fuss. No need to deal with storing users or authenticating users. It’s all available out of the box.

The point of this article is to show how to use Keycloak for authentication in a simple app. I’ll do it by creating a new backend demo application, and show with some code examples how to add Keycloak to the mix.

You can check the example code on this article on this [GitHub repo](https://github.com/agusnavce/keycloak_example) for the examples we are following along.

![](https://cdn-images-1.medium.com/max/1024/1*opUQptlb1bvWzjI3cPUjGA.jpeg)

### Keycloak server on a Docker container

For this example, I’ll be using docker compose to create the necessary resources for us to have authentication in our backend app.

As we are using containers we need the different images for the services. The first image we are using is jboss/keycloak from dockerHub.

For this image, there are a few things you’ll need to know:

- The port you need to expose is 8080 or 8443 if you want SSL.
- Keycloak doesn’t have an initial admin account by default; to be able to log in, you need to provide KEYCLOAK\_USER and KEYCLOAK\_PASSWORDenvironment variables.
- You need to specify a database for Keycloak to use. We are going to use postgres just for the sake of convenience.

{% gist https://gist.github.com/agusnavce/814f043fa9fcdbe94e5483ba85e61112 %}

As we can see in the docker-compose we have two services. The first one is the postgres database. We have defined two variables for the DB in oder to authenticate, POSTGRES\_USER and POSTGRES\_PASSWORD .

One thing to keep in mind is that we need our services to be on the same network since they need to communicate with each other. This is why we created the test network where our services will coexist.

As for the configuration of Keycloak, apart from the considerations mentioned above, we have to add the communication part between Keycloak and the database. In order to do this, all the credentials of the database are passed to the Keycloak service as environment variables.

As we can see, we left the possibility of having SSL as we have port 8443 open. By default Keycloak generates certificates signed by itself, but if we want to have our certificates we have to add a proxy.

So now, we can make docker-compose up -d and and having keycloak up and running.

Once the containers start, go to [https://localhost:8443/auth/admin](http://localhost:8080/auth/admin) and log in using the credentials provided to keycloak. This is the page you should be seeing:

![](https://cdn-images-1.medium.com/max/865/0*J2wcG6baV6-CLBr9.png)

### Simple server configuration

We’ll be running through the following steps in this section:

1. Login to Keycloak
2. Add a Keycloak client for flask
3. Add a new user

What you’re seeing on the page above is the default (master) realm. A realm is the domain in the scope of which several types of entities can be defined, the most prominent being:

- Users: basic entities that are allowed access to a Keycloak-secured system
- Roles: an abstraction of a User’s authorization level, such as admin/manager/reader
- Clients: browser apps and web services that are allowed to request login
- Identity Providers: external providers to integrate with, such as Google, Facebook, or any OpenID Connect/SAML 2.0 based system

The master realm serves as the root for all others. Admins in this realm have permissions to view and manage any other realm created on the server instance. Keycloak authors do not recommend using the master realm to actually manage your users and applications (it is intented as space for super-admins to create other realms), so let’s start by creating a new realm for our app.

You only have to hit the Add realm button and specify the name of the realm:

![](https://cdn-images-1.medium.com/max/725/0*dG1TZ-tQoZs93ANp.png)

Notice that you can now use the top left dropdown to switch between realms.

For simplicity, we’re going to stay with the default SSL mode, which is “external requests”: it means that Keycloak can run over HTTP as long as you’re using private IP addresses (localhost, 127.0.0.1, 192.168.x.x, etc.), but will refuse non-HTTPS connections on other addresses.

You can find the [details for SSL configuration](https://www.keycloak.org/docs/latest/server_installation/index.html#setting-up-https-ssl) in Keycloak documentation.

The final step of the initial server configuration is creating a client. Clients are web services that are either allowed to initiate the login process or provided with tokens resulting from earlier logins. Today we’ll be securing a flask backend, so let’s go to the Clients tab and hit the Create button:

![](https://cdn-images-1.medium.com/proxy/1*USxH7yuMSYuV6_E7zCXcKg.png)

In addition to client name (test-client), we’ve also provided the root URL of the application we’re about to create ([http://localhost:3000/](http://localhost:3000/)). Hit Saveand you’ll be taken to the client details panel.

Note that here we wish to use the OpenID-connect protocol, although it is of course also possible to use SAML, but for the purposes of our demo we shall stick with the former. You can also see that the Access Type attribute is public.

What does this mean, and what our options in this regard?

We have chosen to use OpenID-connect, the Access Type is directly linked to this protocol:

**Confidential access type** concerns server-side clients who need to connect to the browser and ask for a client secret when converting an access code into an access token. This type is to be favored for server-side applications.

**Public access type** is meant for clients that need to connect to the browser. With a client-side application, there is no way of keeping a secret in complete security. Instead of this, it is very important to restrict access by configuring the correct redirection URIs for the client.

**Bearer-only** access type signifies that the application only authorizes bearer token requests. If this option is activated, this application cannot take part in connections with the browser.

It is therefore vital to choose the right type of access according to the client you will be using. Of course, you can have several clients each with a different access type.

Next comes Valid Redirect URIs – this is the URI pattern (one or more) to which the browser can redirect after completing the login process.

Since we picked public access type for our client (and thus anyone can request to initiate the login process), this is especially important: in a real app, you need to take care to make this pattern as restrictive as possible. However, for dev purposes you can just leave it at default.

### Add a User to Keycloak

To add a user, click the Users tab on the left sidebar, then click the Add user button on the ride side of the window.

![](https://cdn-images-1.medium.com/max/1024/0*xeZ56qfUZMICo7MS.png)

On the next page, set the username to user and set the Email Verified switch to on. Then, click the Save button.

![](https://cdn-images-1.medium.com/max/1024/0*X5jpwiRUYr7NiVsD.png)

Click on the Credentials tab, and enter in a password, confirmation, and make sure the Temporary switch is set to off. Then, click the Savebutton.

#### **Integration with flask backend**

We will be using a simple flask app with token authentication. It will have this three basic functionalities:

1. Get the token from keycloak to authenticate to the app
2. Refresh the token to stay logged in
3. Create a user in a realm

{% gist https://gist.github.com/agusnavce/a311f411315c2438a81e1091a554e26e %}

As we can see here we created the main functionalities for user authentication in our backend and also we created an endpoint to create users in our keycloak instance.

To get the tokens and refresh them we just have to use the /protocol/openid-connect/token path with username , password , client\_secret and client\_id as the body. Once we make the api call we can retrieve the tokens from the response.

For the user creation endpoint, we must send the access-token in the request in order to authenticate with keycloak. We’ve created some auxiliar functions that help us retrieve the token and send the request. This is a perfect example to demonstrate how we can protect our endpoints with an authentication token using openid-connect protocol.

> The documentation for the Keycloak API is not easy to find. I found the best documentation for it in this [link](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/) if you want to experiment more with the API.

Finally what we are going to do is to create a simple container that serves the flask application and can communicate with keycloak.

{% gist https://gist.github.com/agusnavce/9c22afd7f61a375101b5ad302b6b7415 %}

Here we have the dockerfile to run the app as a container. Now we have to add the service to our docker-compose file.

{% gist https://gist.github.com/agusnavce/2f24127a0c19d280ddc280fbb65f2f98 %}

With all these component now we have everything we need to add to our application authentication with keyloak. Just use docker-compose up -d and you will have your application app and running with authentication.

### Wraping up

If you are looking for a SSO solution for your application, I suggest you take a look at Keycloak. All the components are very well made and you can have authentication out of the box. The only disadvantage is that documentation is not as easy to find, but once we have this it is as easy as using any other api.

I hope you take with you some ideas on how to work with this framework and how to use it on your applications. Again, you can find all the code for this project at this [Github repo](https://github.com/agusnavce/keycloak_example).

Please share any thoughts or comments you have. Feel free to ask and correct me if I’ve made some mistakes. If you want to get in touch with me you can find me in twitter under [@agusnavce](https://twitter.com/agusnavce).

Thanks for your time!