It is a tool for “Identity and Access Management”, Keycloak is an open-source tool currently licensed with Apache License 2.0. It is also an upstream project for Red Hat SSO.
Multiple Protocols Support : As for now Keycloak supports three different protocols, namely - OpenID Connect, OAuth 2.0 and SAML 2.0.
SSO : Keycloak has full support for Single Sign-On and Single Sign-Out.
Admin Console : Keycloak offers web-based GUI where you can “click out” all configurations required by your instance to work as you desire.
User Identity and Accesses : Keycloak can be used as a standalone user identity and access manager by allowing us to create users database with custom roles and groups. This information can be further used to authenticate users within our application and secure parts of it based on pre-defined roles.
Social Identity Providers : Additionally, Keycloak allows us to use Social Identity Providers. It has built-in support Google, Twitter, Facebook, Stack Overflow but, in the end, you have to configure all of them manually from admin panel. The full list of supported social identity providers and their configuration manual can be found in Keycloak documentation.
Server : Standalone application is downloadable from Keycloak page in form of a tar or zip archive with all scripts, docs, and assets needed to work normally. As for now, there are two main versions of this distribution: one is powered by WildFly server while the other is powered by Quarkus. It is now in preview stage so some unexpected error may occur.
Docker Image : Distribution appropriate for Docker, Podman, Kubernetes, and OpenShift. There are two official docker images for Keycloak: one is held in Quay Container Registry - quay.io/keycloak/keycloak, the second one is held in Docker Hub - jboss/keycloak. You can download both of them with a simple docker pull command.
Operator : Distribution for Kubernetes and OpenShift based on Operator SDK.
1. Download Keyclock server https://www.keycloak.org/downloads
Note : for windows download ZIP package
2. Start Keyclock server
unzip the package and hit the following command : sh bin/kc.sh start-dev
3. Create Admin user
4. go to Administration console and login with created user
5. create a realm (a component that holds user, role and role based authentications)
6. create a client (a component that we use in our springboot app to communicate)
7. create a role
8. create a user and set username and password using credential tab
9. map user and roles
10. add keycloak dependencies
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-spring-boot-starter</artifactId> </dependency>
<dependencyManagement> <dependencies> <dependency> <groupId>org.keycloak.bom</groupId> <artifactId>keycloak-adapter-bom</artifactId> <version>19.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
11. add properties
keycloak: realm: demo-realm auth-server-url: http://localhost:8080/auth resource: keycloak-demo #client-id public-client: true bearer-only: true
12. create configuration class
package com.javatechie.keycloak.config; import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; 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.context.annotation.Import; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 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 @EnableGlobalMethodSecurity(jsr250Enabled = true) //jsr250Enabled will allow us to write @RolesAllowed() @Import(KeycloakSpringBootConfigResolver.class) public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { /** * Registers the KeycloakAuthenticationProvider with the authentication manager. */ @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { KeycloakAuthenticationProvider authenticationProvider = new KeycloakAuthenticationProvider(); authenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); auth.authenticationProvider(authenticationProvider); } /** * Defines the session authentication strategy. */ @Bean @Override protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); } @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); http .authorizeRequests() .anyRequest().permitAll(); } }
13. configuring role in our code
package com.javatechie.keycloak; import com.javatechie.keycloak.entity.Employee; import com.javatechie.keycloak.service.EmployeeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.security.RolesAllowed; import java.util.List; @SpringBootApplication @RestController @RequestMapping("/employees") public class SpringBootKeycloakExampleApplication { @Autowired private EmployeeService service; //this method can be accessed by user whose role is user @GetMapping("/{employeeId}") @RolesAllowed("user") // only user role can allow this method public ResponseEntity<Employee> getEmployee(@PathVariable int employeeId) { return ResponseEntity.ok(service.getEmployee(employeeId)); } //this method can be accessed by user whose role is admin @GetMapping @RolesAllowed("admin") // only admin role can allow this method public ResponseEntity<List<Employee>> findALlEmployees() { return ResponseEntity.ok(service.getAllEmployees()); } public static void main(String[] args) { SpringApplication.run(SpringBootKeycloakExampleApplication.class, args); } }
14. testing our code using postman with following parameters
Note - in postman's authorization type select OAuth 2.0 Access Token Url : http://localhost:8080/auth/realms/demo-realm/protocol/openid-connect/token Client ID : keycloak-demo Scope : openid Grant Type : Password Credentials Username : <username> Password : <password> Access token : <access token>
source : https://www.keycloak.org/
source code : https://github.com/viveksoni100/keycloak_learning