Scalac
Published in

Scalac

The Ultimate Guide

User Authentication with Keycloak

Part 1: React Front-End

keycloak authentication

Providing authentication and authorization for the non-public-facing components of your application is an important part of many systems. But all major Scala frameworks come ready-equipped with some native tools for doing that, with complexity and comprehensiveness ranging from basic HTTP schemes with Akka HTTP’s SecurityDirectives to numerous Play plugins such as Deadbolt 2 or Silhouette.

But it can be difficult to get what you need out of some of these. And if you have to relearn them for every new framework — it ain’t nice either.

Learn how to overcome the additional overhead when moving to an unfamiliar tech stack!

Enter Keycloak server. What is it? To quote the authors:

Keycloak is an open-source​ Identity and Access Management solution aimed at modern applications and services. It makes it easy to secure applications and services with little to no code.

Authentication with Keycloak brings to the table virtually every feature you might want regarding user authentication and authorization. Some of these include:

  • single sign-on and sign-out, with possible integration with Kerberos (LDAP or Active Directory),
  • support for OpenID Connect and SAML 2.0,
  • log in via social media,
  • user account management via both the web console and REST API,
  • fine-grained authorization for different services.

And many others.

Today, we’ll learn how to set up your Keycloak server and use it to secure a React-based browser app. In the next part of this series, we’ll be looking into integrating it with a Scala backend. So, let’s get started!

Running a Keycloak server

There are multiple ways to host your Keycloak instance. If you’d like to do it the traditional way, you can download the distribution file from https://www.keycloak.org/downloads.html and run the bin/standalone.sh script.

However, if you’re a containerization fan like me, you’ll find an jboss/keycloak image in Docker Hub. In this situation, there are three things you'll need to know:

  • the port you need to expose is 8080,
  • Keycloak doesn’t have an initial admin account by default; to be able to log in, you need to provide KEYCLOAK_USER and KEYCLOAK_PASSWORD environment variables,
  • you need to specify a database for Keycloak to use, with the easiest option being an embedded H2 instance; if you’d like to provide another (PostgreSQL, MySQL, and MariaDB are supported out-of-the-box), you can follow the instructions in the image reference.

Keeping this in mind, you can start the container:

docker run -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -e DB_VENDOR=H2 jboss/keycloak

Once the container starts, go to http://localhost:8080/auth/admin and log in using the credentials provided (admin/admin). This is the page you should be seeing:

Server configuration

What you’re seeing on the page above is the default (master) realm. A realm is a domain in 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: a User’s authorization level, such as admin/manager/reader.
  • Clients: browser apps and web services that are allowed to request a 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 of the others. Admins in this realm have permission to view and manage any other realm created on the server instance. Keycloak authors don’t recommend using the master realm to manage your users and applications (it is intended as space for super-admins to create other realms).

So let’s start by creating a new realm for our app.

Mouse over the realm name in the top left-hand corner of the console and hit the Add realm button. The only thing you need to specify for the new realm is its name - let's go with MyDemo:

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

For simplicity, we’re going to stay with the default SSL mode, which is “external requests”. This 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’ll find the details for SSL configuration in the Keycloak documentation. If you’d like to use a trusted CA certificate in place of a self-signed one, you can get it easily with Let’s Encrypt by following these instructions.

The next thing to do is to define a test user for our new realm. Make sure that the MyDemo realm is selected, go to the Users tab and hit Add user. For now, the only thing you'll need to provide is the username. Let's call him John:

After creating the user, you’ll need to set up his password. Go to Credentials tab, enter the new password twice and hit Reset Password (in a real application.

You can either allow users to self-register or configure an SMTP server and use the Verify Email and Update Password actions to enable admin-created users to choose their passwords themselves).

To check if the new user works, open a new incognito window in your browser. Then go to http://localhost:8080/auth/realms/MyDemo/account and try logging in with the username john and the password you provided earlier.

Since we left the Temporary option turned on when resetting the password, you'll be asked to provide a new one on the first login. Afterwards, you'll be taken to your account management panel:

Among other things, this will allow you to provide your profile information (which may or may not be enforced by the admin), change your password, and see all your active login sessions. For now, let’s update the Email, First name and Last name fields with whatever values you like, then get back to the admin window.

The final step of the initial server configuration is to create a client. Clients are browser apps and web services that are either allowed to initiate the login process or have been provided with tokens resulting from earlier logins.

Today we’ll be securing a React-based front-end, so let’s go to the Clients tab and hit the Create button:

Keycloak React-based front-end

In addition to the client name ( my-react-client), we've also provided the root URL of the application we're about to create ( http://localhost:3000/). Hit Save and you'll be taken to the client details panel.

Keycloak

The number of options visible here can be a bit daunting, but really, there are just three that are important at the moment. The first is Access Type with three possible values:

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

Since we picked public access type for our client (and thus anyone can ask to initiate the login process), this is especially important. In a real app, you will need to make sure you make this pattern as restrictive as possible, otherwise, you could open your system to phishing attacks! However, for dev purposes, you can just leave it at default.

The last of the important options is Web Origins, which governs CORS requests. Again, for dev purposes the default value is fine.

One last thing we’ll need is the client configuration to use with our app. Go to the Installation tab and select Keycloak OIDC JSON as the format:

  • Bearer-only - this is for services that rely solely on the bearer token included in the request and never initiate login on their own. It's typically used for securing the back-end.
  • Confidential - clients of this type need to provide a secret in order to initiate the login process.
  • Public - since we have no real way of hiding the secret in a JS-based browser app, this is what we need to stick with.

Download this JSON and keep it. We’ll be needing it later.

Now your Keycloak server setup is complete — let’s start whipping up our front-end code!

Creating the web app

We’re going to create a simple React-based app that allows the user to navigate between two components: one public and one that requires logging in. Instructions will be step-by-step, for the benefit of those readers who have had no previous exposure to React. If you’re eager to have a browse through the finished code, you can just download it from my GitHub repo.

I’m assuming you have npm installed - if not, you can get it from here. We'll be using the create-react-app script, so install this as well if you don't already have it:

npm install -g create-react-app

Now we can use it to create a template for our application:

create-react-app keycloak-react

Firstly, we’ll need to add some dependencies. Open package.json and add the following two items:

View the code on Gist.

Run the following to download the new dependencies:

npm install

Please note: instead of downloading the Keycloak JavaScript adapter, it’s possible to include it directly from your Keycloak server (it’s hosted at /auth/js/keycloak.js), which has the added benefit of not having to worry about mismatched versions. However, React doesn't play nice with remote URL imports, so it's easier to do it this way.

Also worth mentioning: 4.0.0 is the first version of Keycloak to use ES6 Promises instead of homegrown promise-like objects. If you have to work with an older version for any reason, Raymond DeCampo has a wrapper that could help.

Moving on. Let’s replace the contents of src/App.js with our skeleton:

View the code on Gist.

As you can see, this is just a Router providing navigation between two other components. Let’s add the first of those, src/Welcome.js:

View the code on Gist.

Nothing particularly fancy here, just some generic text. The next one should be a bit more interesting — put it at src/Secured.js:

View the code on Gist.

As soon as the component is mounted into the DOM, we can create the Keycloak object by providing client configuration:

View the code on Gist.

Remember the JSON you downloaded from the admin panel? Put it into the public/keycloak.json to get the above to work. Alternatively, you could pass a matching JavaScript object to Keycloak directly:

View the code on Gist.

login-required is one of two possible values to be passed as an onLoadparameter. This will authenticate the client if the user has already logged into Keycloak, or redirect the browser to the login page if he hasn't. The other option is check-sso: this will only authenticate the client if the user has already logged in, otherwise the client will remain unauthenticated without automatic redirection.

Time to check it out — run npm start and your browser should open automatically:

Follow the secured link and you’ll be redirected to the login page:

Log in as john with the password you specified earlier, and voilà:

You’ll find you can now navigate between the two components without having to log in again. If you’d like to know a bit more about the magic that happened here, I recommend reading through the documentation on OpenID Authorization Code flow, which Keycloak uses by default (Implicit and Hybrid flows are also supported).

As a test, open a new incognito window and try going through the login process again, but use 127.0.0.1 instead of localhost. Since the redirect URI pattern, we specified in the admin panel earlier only included the latter and not the former, you should get an error on the login page.

Let’s expand our app a little bit by adding the logout functionality and some user data extraction. We’ll start with the latter — add the following as src/UserInfo.js:

View the code on Gist.

This component accepts a Keycloak instance from its parent, then uses the loadUserInfo method to extract the user's data.

Now for the logout button, place the following in src/Logout.js:

View the code on Gist.

Similarly, this accepts a Keycloak instance from the parent, then uses its logout method. Note that it has to be called last - otherwise it would redirect you to the login form again.

Let’s include these new components in src/Secured.js:

View the code on Gist.

As expected, clicking the logout button forces you to have to log in again, the next time you try to access the Secured component.

This concludes the demonstration for today — you can see now how easy and quick it is to provide front-end authentication with Keycloak. Don’t miss the second part of this series, where we’ll be looking into securing your back-end using bearer tokens!

Read more

The second part is now available!
Continue reading here:
User Authentication with Keycloak — Part 2: Akka HTTP backend

Originally published at https://scalac.io on February 14, 2019.
Author Jakub Mikulski

--

--

--

We specialize in functional programming, distributed computing, blockchain, analytical dashboards,and data engineering. Work with us if you needa team to build your dedicated solution, a consultation to move forward with your project or a team extension to get rid of bottlenecks

Recommended from Medium

Avalanche: The collaborative blockchain

Using namespaces and autoloading with Composer in WordPress plugins

How to Scale your Remote Access VPN on AWS

Olympics Lab round-up

How to stop shitting your pants when seeing a dynamic programming problem

Reflective on “Welcome to the Jungle or, A Heterogeneous Supercomputer in Every Pocket” by Herb…

Powering a search engine with Amazon SageMaker

Fixing the coding part of interviews

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
Scalac

Scalac

Scalac is a web & software development company with 122 people including Backend, Frontend, DevOps, Machine Learning, Data Engineers, QA’s and UX/UI designers

More from Medium

Protobuf and gRPC In Action With Kotlin

Enable Smile serialization on requests using Spring WebClient (Kotlin)

Error Handling the FP way; using Kotlin

Building Micronaut applications with Micronaut Mongo Reative

Photo by <a href=”https://unsplash.com/@fabianmardi?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Fabian Mardi</a> on <a href=”https://unsplash.com/s/photos/snow?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>