Integrating Keycloak with Spring Boot for GitHub Login
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,

Then select developer settings,

Select OAuth apps and add a new OAuth app,

Step 3:
Generate client credentials,

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.

Spring Boot code:
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,


Now let us try to login to our “/homepage” with help of github credentials,
http://localhost:8082/homepage will redirect to below page,

Click on GitHub,

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

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.