Securing a JavaScript App Using Keycloak
In this post I am going to explain how to secure a Vanilla JS (pure JavaScript) application using Keycloak identity & access management system.
I will be explaining all the configuration and development tasks you need to do for this integration under three main sections.
- Keycloak configuration
- Js app configuration
- Running the app ( demonstration )
Let’s get started.
1. Keycloak Configuration
As the first step you need to have running Keycloak server. I am using a Keycloak server running locally in my PC on the url http://localhost:8080
You can use a locally running Keycloak instance or a hosted one in a remote server as you prefer.
As the initial step, we need to create a new client in the Keycloak server in order to connect the JS application. To do that, you need to visit the admin web console and select clients section as I have shown below.
Once visited the clients page, click on Create client button.
Once Create client button is clicked, a new window will appear and there you need to provide client details including theclient id (which should be unique for the realm). I have provided my client id as js-client
Once you provided the client id ,click Next button, then below page will appear and there you need to provide the authentication flow of the client. Here I have enabled standard flow which is OpenID Connect Authorization Code Grant type.
Nothing to worry if you are not familiar with authentication flows /OIDC grant types. You can learn them later, for the moment just follow the instructions.
PS: You should learn authentication flows later if you are expecting to become an expert in identity & access management :-)
Client authentication switch is disabled for this client since this is a HTML/JS application which is supposed to be loaded on user’s web browser. Therefore there is no point of enabling client authentication for public clients.
Enabling client authentication gives you a client secret to use in addition to the client id , since the application is loaded on the web browser client secret can simply be read by inspecting HTML and JS content
After enabling standard flow click Next. After that you can configure login settings for the client as shown below. Two important URLs need to be added here.
First one is a valid redirect URI. Once the user is successfully authenticated, she will be redirected back to the JS application. JS application’s URL should be added to the valid redirect URIs section.
If you prefer, you can set
*(any url) as a valid redirect URI for testing purpose. But never use that in a production setup.
After setting redirect URIs you need to set web origins. JS application communicates with the Keycloak server directly for different reasons such as token refreshes, etc.
If the web origin property is not properly set, browser console will show CORS (Cross Origin Resource Sharing) related errors.
Once those fields are updated, click Save. Then you will be redirected to the configuration page of the js-client
This is all we need to do as Keycloak level configurations. Let’s visit the JavaScript application.
2. JavaScript App Configuration
Source code of the application is already available on Github and it will be easier for you to understand the code if you can open it in a code editor.
Let me take you through the important sections of the code.
Get Nishada Liyanage’s stories in your inbox
Join Medium for free to get updates from this writer.
I have implemented the whole code in two files (index.html & main.js) so it will make easier for you to understand.
Section 1 : HTML Code
index.html file is very simple for understanding.
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/keycloak-js@22.0.3/dist/keycloak.min.js"></script>
<script type="text/javascript" src="./main.js"></script>Above are the scripts and stylesheets I have imported to my code.
Bootstrap css fileis used to add styles.- Keycloak SDK is imported by using the Keycloak javascript adapter dependency
keycloak.min.js.When you import this file you need to make sure the version is matching to the Keycloak server version. - Third import is the
main.jsfile ( will be going through this shortly)
I dont think you need any explanation to the below code component. Which contains all the buttons and text area I have used to demonstrate the application.
<div class="container">
<div class="jumbotron mt-4">
<h1 class="display-4">Keycloak - Javascript Integration</h1>
<p class="lead">A pure javascript web app</p>
<div class="mt-4">
<button id="loginBtn" class="btn btn-primary">Login</button>
<button id="logoutBtn" class="btn btn-secondary">Logout</button>
<button id="isLoggedInBtn" class="btn btn-info">Is Logged In</button>
<button id="accessTokenBtn" class="btn btn-warning">Access Token</button>
<button id="showParsedTokenBtn" class="btn btn-dark">Show Parsed Access Token</button>
<button id="callApiBtn" class="btn btn-success">Call API</button>
</div>
<div class="mt-4">
<textarea id="output" class="form-control" rows="5" placeholder="Output will be displayed here..."></textarea>
</div>
</div>
</div>Section 2: JavaScript Code
Let’s begin from the Keycloak object constructor
const keycloak = new Keycloak({
url: 'http://localhost:8080',
realm: 'master',
clientId: 'js-client'
});This is where the keycloak object is created. This object is used to communicate with the Keycloak server. Three arguments are provided to the constructor.
url: Keycloak server url is provided as the url propertyrealm: We are using themasterrealm for this demonstrationclientId: this is the id of the client we created earlier.
keycloak.init({
onLoad: 'check-sso' // 'check-sso', 'login-required'
}).then(function(authenticated) {
....
})Keycloak init function is used to initialize the Keycloak client object created above. init function accepts a json object as an argument and that json object may have multiple properties.
onLoad: This property determines the behaviour of the JS application when a user tries to access. withcheck-ssovalue, JS application can be accessed even without having a valid session ( without signing into Keycloak). If user must have a valid session before accessing this application,login-requiredvalue can be provided. withlogin-requiredvalue, if the user does not have a valid session she will be redirected to the Keycloak login pageflow: You can provide which OpenID Connect grant type should be used with flow property. By defult it is usingAuthorization Codegrant typepkceMethod: Proof key for code exchange method. By default it is using SHA256 based PKCE
Above mentioned are a few of the important parameters and you can find all the init parameters by visiting the Keycloak documentation. https://www.keycloak.org/docs/latest/securing_apps/#methods
Rest of the JS code contains few buttons and a text area I have created to demonstrate the functionalities of the keycloak-js SDK.
By inspecting the code you can understand things like how to login, logout, fetch the access token, etc. Full api documentation is available in the below link.
https://www.keycloak.org/docs/latest/securing_apps/#api-reference
Calling an API
Below code component can be used to call an external API with the access token from the JavaScript application.
fetch('https://4b215443be964e33.api.mockbin.io/', {
headers: {
'Authorization': 'Bearer ' + keycloak.token
}
})
.then(response => response.json())
.then(data => {
logToTextarea('API call successful: ' + JSON.stringify(data));
console.log(data);
})Rest of the code is easy to understand just by looking at the code. Please put a comment if you need any clarification regarding the code.
Let’s go to the demonstration.
3. Running the application
My keycloak server is already running locally on http://localhost:8080
I need to server my JS application using a static file server. Here I am using a simple python http server.
You can use any server as you prefer for serving static files (nginx, apache, S3 bucket etc.)
Since python is already installed into my pc I start the http server by a single command.
python3 -m http.server 3000 #serve file of the current directory on port 3000Now my JavaScript application is available on http://localhost:3000
Once visited the JS App, we can see the below landing page.
Buttons can be used to test and see different functionalities of the application. I have only added few functionalities and rest of the supported functionalities can be found in the documentation ( See the reference).
I believe now you got a clear idea about the Keycloak — JS App integration and if you have any question please put a comment.
Thank you . . .
Source Code
https://github.com/hexadefence/keycloak-js-example
Reference
https://www.keycloak.org/docs/latest/securing_apps/#_javascript_adapter







