Fork me on GitHub

Programming, Internet & more

Authentication with Spring Boot, AngularJS and Keycloak

In this tutorial, I want to show you how to combine Keycloak with AngularJS and Spring Boot.

The result will be a small application where you will get a frontend written in AngularJS and the big topics regarding authentication like user-registration, password reset, login page etc. are already solved.

The backend is implemented with Spring Boot and will provide a REST API with business services exposed. Authentication in the backend is also solved by using Keycloak which means that all REST endpoints will be secured and that you will get all the user information in the backend as well as in the frontend.

Requirements

We will use the following tools and frameworks to build the application:

Maven (Version 3.3.9)
Spring Boot (Version 1.3.3.RELEASE)
Keycloak (Version 1.9.1.Final)
AngularJS (Version 1.5.0)

Create a realm in Keycloak

Start up Keycloak by using one of the Standalone executeables in the /bin directory of Keycloak which will start Keycloak immediately by using the bundled WildFly application server.

After the startup, open up a browser and navigate to http://localhost:8080.

If this is the first time you start Keycloak it is required to create an admin user.

After you have created the admin user, use this user to login into the Administration Console. By default Keycloak uses the Master realm to manage its own users. You should never use this realm to authenticate your own application. Instead create your own realm for the authentication of your application.

Create a new realm by hovering over the Master realm and click on the “Add realm” button. Enter a name, we will use Demo-Realm, and click on “Create”. After that you will be navigated to the configuration page of the realm.

Open the “Login” tab and enable the features “User registration” and “Forgot password”. By enabling, these features will be added to the login page automatically and will cover the common use-cases that appear in nearly every web application.

Create roles in Keycloak

Now, lets add some roles that can be assigned to users later on to handle authorization. We need two roles that will come into play later on. One is the admin role and the other one is the manager role.

Click on the “Roles” link in the navigation and after that, click on the button “Add Role” at the right side of the screen. This will navigate you to the “Add Role” screen. Enter admin as role name and click on “Save”. Create another role named manager.

Create clients in Keycloak

After we have created our roles we can create the clients for our application. We will need two clients. One for the frontend application and one for the REST backend.

Let’s start by creating the frontend client. Click on the “Clients” link in the navigation and then use the “Create” button to create a new client.

Use tutorial-frontend as client id and click on “Save”.

You will be navigated to the client settings. Use the access type public and the following URLs and save the client:

  • Valid Redirect URIs: http://localhost:8000/*
  • Base URL: http://localhost:8000/index.html
  • Web Origins: http://localhost:8000

Now the frontend client is completely configured and can be used.

Lets create another client for the backend and name it tutorial-backend. This time configure the access type as bearer-only because the REST backend should only be called when a user has already logged in.

Now the basic configuration in Keycloak is done and we can start building the applications.

Frontend application with AngularJS

We want to build a small Angular application that is secured by a login page and where access is restricted to registered users only. Therefore every request which goes to the Angular application should be checked if it comes from a registered user or not. If a request does not come from a registered user, the request will be redirected to the login page where a user can register.

To interact with Keycloak from our AngularJS application, Keycloak is providing a JavaScript-Adapter directly on the Keycloak server. This adapter will be used to check if a request is authenticated and can be integrated in our application by including the JavaScript file into our html page:

<script src="//localhost:8080/auth/js/keycloak.js"></script>

Futhermore we have to configure the KeyCloak adapter to ensure it knows who our application is and where to find the Keycloak server. We can provide this information as a json file which can be downloaded directly from the Keycloak server.

To get the json file, open the Keycloak administration console and navigate to the frontend client page. Then open the “Installation” tab and choose “Keycloak OIDC JSON” as format. Then download the JSON file and store it in the angular application as /keycloak/keycloak.json.

One important thing to know is because we are only allowing registered users to have access to the application we have to manually bootstrap AngularJS and we cannot rely on the automatic bootstrapping with the ng-app directive.

The following code demonstrates how to authenticate a request and bootstrap angular only if the request comes from a registered user:

// on every request, authenticate user first
angular.element(document).ready(() => {
    window._keycloak = Keycloak('keycloak/keycloak.json');

    window._keycloak.init({
        onLoad: 'login-required'
    })
    .success((authenticated) => {
        if(authenticated) {
            window._keycloak.loadUserProfile().success(function(profile){
                angular.bootstrap(document, ['keycloak-tutorial']); // manually bootstrap Angular
            });
        }
        else {
            window.location.reload();
        }
    })
    .error(function () {
        window.location.reload();
    });
});

If an unregistered user opens the application he will be automatically redirected to the Keycloak login page. In the application we can access user information like login name by getting the user profile with loadUserProfile().

That is basically all what is needed to secure our Angular application. To ensure the user information is transmitted to the backend we also have to add the users access token to the request header while calling a backend REST service. This can be done like this application wide:

// use bearer token when calling backend
app.config(['$httpProvider', function($httpProvider) {
    var token = window._keycloak.token;    
    $httpProvider.defaults.headers.common['Authorization'] = 'BEARER ' + token;
}]);

Backend application with Spring Boot

The backend application should be secured against unauthorized access. Therefore, like in the frontend, only requests coming from registered users should be accepted.

First, it is important to add the maven Keycloak dependencies for Tomcat and Spring Boot:

<dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-tomcat8-adapter</artifactId>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-boot-adapter</artifactId>
            <version>${keycloak.version}</version>
        </dependency>

Then we have to configure keycloak just like we did in the frontend application. This time the configuration is done the Spring Boot way in the application.properties file:

keycloak.realm = Demo-Realm
keycloak.realmKey = MI...
keycloak.auth-server-url = http://localhost:8080/auth
keycloak.ssl-required = external
keycloak.resource = tutorial-backend
keycloak.bearer-only = true
keycloak.credentials.secret = e12cdacf-0d79-4945-a57a-573a833c1acc

The values can be retrieved from the “Installation” tab in the administration console of Keycloak for the backend client. One important thing here is to not forget the secret. The secret can be retrieved from the “Credentials” tab of the backend client.

To secure the REST API endpoints a few other entries in the application.properties file are important:

keycloak.securityConstraints[0].securityCollections[0].name = spring secured api
keycloak.securityConstraints[0].securityCollections[0].authRoles[0] = admin
keycloak.securityConstraints[0].securityCollections[0].authRoles[1] = manager
keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /api/*

The patterns property defines the pattern of the API endpoints with * acting as wildcard. That means every endpoint under api like /api/contracts or /api/users is protected by Keycloak. Every other endpoint that is not explicitly listed is NOT secured by Keycloak and is publicly available.

The authRoles property defines which Keycloak roles are allowed to access the defined endpoints.

If everything is configured correctly the Keycloak adapter for Spring Boot should intercept incoming request automatically and reject unauthorized requests.

To access detailed user information in the backend we can use the KeycloakPrincipal class from the Keycloak-SpringBoot adapter. The KeycloakPrincipal will automatically be injected by Spring if used in a REST controller class as method parameter. Detailed user information can then be retrieved by using the AccessToken like this example in a REST controller:

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public void getUserInformation(KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal) {
        AccessToken token = principal.getKeycloakSecurityContext().getToken();
       
        String id = token.getId();
        String firstName = token.getGivenName();
        String lastName = token.getFamilyName();

        // ...
    }

In the full example you will see that I have build a MethodArgument Resolver to avoid having to deal with the Principal in the REST controllers but that is absolutely not necessary and just for convenience.

Demo

The simplest way to start up a demo is to clone the application source with:

git clone https://github.com/cternes/slackspace-angular-spring-keycloak

Then you can either configure the frontend and backend application with the correct settings from Keycloak as described above OR use the existing KeyCloak configuration in keycloak/demo-realm.json to import the realm in Keycloak and avoid having to manually configure the applications.

After that use maven to start both applications with the following command:

mvn spring-boot:run

Then navigate to http://localhost:8000 and you should find yourself landing on the Keycloak login page. Register yourself as a new user. After registering you will be redirected back to the Angular application and should see some details about your user.

Please note that currently your user is not associated to any role defined earlier. That means accessing the backend is impossible because we have only allowed managers and admins to access the backend. To give your user access to the backend we have to map your user to a role.

To do this, open the Keycloak admin console and navigate to “Users”. Then click on the button “View all users” and click on your username. After that navigate to the “Role Mappings” tab and assign the role “manager” to your user.

Now open up the Angular app again and you should see a “Call backend service” button that only managers can see. Click on it and some contracts from the backend should be returned together with your user information which comes also from the backend.

This proves that the frontend and the backend is correctly secured by Keycloak.

Source-Code

As always, you can find a full working example at GitHub.

Category: spring
-->

7 Comments

  1. Manuel Palacio
    Posted June 3, 2016 at 13:57 | Permalink

    Excellent tutorial. Thank you! Do you happen to know if it’s possible to use KeyCloak’s client libraries to integrate with other SSO solutions that support SAML?

    • Christian
      Posted June 3, 2016 at 15:00 | Permalink

      I don’t know for sure but as the JS adapter is written for keycloak, I doubt that it will work with another provider.

      • Manuel Palacio
        Posted June 6, 2016 at 12:21 | Permalink

        You are right, it’s not going to work. My plan is to develop my application to integrate with KeyCloak like in your tutorial and then use KeyCloak as the identity broker that integrates with other IDPs. That should work fine. Thanks.

  2. Preethi
    Posted July 1, 2016 at 16:45 | Permalink

    Excellent Tutorial.I see some issue in accessing the application via IE11.

  3. Daniel Abella
    Posted August 9, 2016 at 14:22 | Permalink

    Great tutorial! The best tutorial about this technology.

  4. Posted October 24, 2016 at 21:26 | Permalink

    Awesome! Trying it out now…

    • Posted October 24, 2016 at 21:48 | Permalink

      Working perfectly! I was having some issue to get this working and internet lacks of resource on this topic. I’m glad I found this article and thank you for sharing.

Post a Comment

Your email is kept private. Required fields are marked *

*
*