Spring Boot + Keycloak Integration – Login with Github

In this tutorial, we’ll examine how to use Keycloak to access a resource using our github credentials.

To understand how to login with keycloak using spring boot kindly refer here – Securing Spring Boot Application with Keycloak.

In our previous article we have configured Keycloak by adding username and password in keycloak server.

In this article let us login to our application with help of github credentials.

First let us configure our github, We need to make github to accept the authorization requests from our client.

Step 1:

First let us create an identity provider in our keycloak,

Make sure to not the Redirect URI -> http://localhost:8080/realms/javainfiniteapp/broker/github/endpoint

Step 2:

Go to github and login,

Go to settings,

settings

Then select developer settings,

developer settings

Select OAuth apps and add a new OAuth app,

OAuth app

Step 3:

Generate client credentials,

details

We have generated client credentials and please note we have used that Authorization callback URL which we generated from Keycloak. (http://localhost:8080/realms/javainfiniteapp/broker/github/endpoint)

Client name to identify our client and homepage url is the server and port where our application is running.

Copy the ClientId and Client Secret.

Step 4:

In our keycloak Identity provider, fill the client ID and client Secret values and save.

clientId and clientSecret

Spring Boot code:

Project Structure:

Project Structure

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.javainfinite</groupId>
	<artifactId>keycloak</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Keycloak Security</name>
	<description>KeyCloak Security Example</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.keycloak/keycloak-spring-boot-starter -->
		<dependency>
			<groupId>org.keycloak</groupId>
			<artifactId>keycloak-spring-boot-starter</artifactId>
			<version>15.0.2</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

KeycloakController.java

package com.javainfinite.keycloack.controller;

import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.keycloak.representations.AccessToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;

@RestController
public class KeycloakController {

    @GetMapping("/login")
    public String login() {
        return "Welcome to login screen";
    }

    @GetMapping("/homepage")
    public String homepage(Principal principal) {
        KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) principal;
        AccessToken accessToken = token.getAccount().getKeycloakSecurityContext().getToken();
        return "Welcome to homepage, " + accessToken.getPreferredUsername() + " successfully logged in";
    }


}

KeycloakConfigurationResolver.java

package com.javainfinite.keycloack.security;

import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class KeycloakConfigurationResolver {

    @Bean
    public KeycloakConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }
}

KeycloakSecurity.java

package com.javainfinite.keycloack.security;

import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;

@KeycloakConfiguration
public class KeycloakSecurity extends KeycloakWebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(
                new SessionRegistryImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
                .antMatchers("/homepage").authenticated()
                .anyRequest().permitAll();
        http.csrf().disable();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

}
  • @KeycloakConfiguration: It includes EnableWebSecurity and Configuration and provides Keycloak based configurations
  • SessionAuthenticationStrategy:
    • Allows pluggable support for HttpSession-related behaviour when an authentication occurs.
    • Typical use would be to make sure a session exists or to change the session Id to guard against session-fixation attacks. for details click here
  • ConfigureGlobal:
    • Keycloak Authentication provider is included with authentication manager.
    • In our Configure method, we have made homepage to be authenticated and authorized for the users with role – standard

We have secured “/homepage” endpoint and other endpoint does not require any permission.

application.properties

keycloak.realm=javainfiniteapp
keycloak.auth-server-url=http://localhost:8080
keycloak.resource=javainfinite-client
keycloak.credentials.secret=Afg7GGxqXXRg0tEJq6XCyfFP3RJ0dREO
keycloak.use-resource-role-mappings=true
server.port=8082

KeycloakSecurityApplication.java

package com.javainfinite.keycloack;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class KeycloakSecurityApplication {

	public static void main(String[] args) {
		SpringApplication.run(KeycloakSecurityApplication.class, args);
	}

}

Now let us run our application,

application started
Able to login to access without any permissions.

Now let us try to login to our “/homepage” with help of github credentials,

http://localhost:8082/homepage will redirect to below page,

login page

Click on GitHub,

GitHub login

Once we login with our account then we will get an prompt webpage to verify whether the access can be provided,

Authorization Page

Once we grant the permission we will be able to login to our homepage.

We have successfully implemented Keycloak with github login using Spring boot.

For any doubts or queries or needed help with implementing above example please do leave a comment

Code can be downloaded here.

By Sri

Leave a Reply

Your email address will not be published.