├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── javatechie │ │ └── keycloak │ │ ├── SpringBootKeycloakExampleApplication.java │ │ ├── config │ │ └── SecurityConfig.java │ │ ├── entity │ │ └── Employee.java │ │ ├── repository │ │ └── EmployeeRepository.java │ │ └── service │ │ └── EmployeeService.java └── resources │ ├── application.properties │ └── application.yml └── test └── java └── com └── javatechie └── keycloak └── SpringBootKeycloakExampleApplicationTests.java /README.md: -------------------------------------------------------------------------------- 1 | # spring-boot-keycloak 2 | Securing Spring Boot REST APIs with Keycloak 3 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.6 9 | 10 | 11 | com.javatechie 12 | springboot-keycloak-example 13 | 0.0.1-SNAPSHOT 14 | springboot-keycloak-example 15 | Demo project for Spring Boot 16 | 17 | 1.8 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-data-jpa 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web 27 | 28 | 29 | 30 | com.h2database 31 | h2 32 | runtime 33 | 34 | 35 | org.projectlombok 36 | lombok 37 | true 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-test 42 | test 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-security 47 | 48 | 49 | org.keycloak 50 | keycloak-spring-boot-starter 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.keycloak.bom 58 | keycloak-adapter-bom 59 | 15.0.2 60 | pom 61 | import 62 | 63 | 64 | 65 | 66 | 67 | 68 | org.springframework.boot 69 | spring-boot-maven-plugin 70 | 71 | 72 | 73 | org.projectlombok 74 | lombok 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/keycloak/SpringBootKeycloakExampleApplication.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.keycloak; 2 | 3 | import com.javatechie.keycloak.entity.Employee; 4 | import com.javatechie.keycloak.service.EmployeeService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import javax.annotation.security.RolesAllowed; 15 | import java.util.List; 16 | 17 | @SpringBootApplication 18 | @RestController 19 | @RequestMapping("/employees") 20 | public class SpringBootKeycloakExampleApplication { 21 | 22 | @Autowired 23 | private EmployeeService service; 24 | 25 | //this method can be accessed by user whose role is user 26 | @GetMapping("/{employeeId}") 27 | @RolesAllowed("user") 28 | public ResponseEntity getEmployee(@PathVariable int employeeId) { 29 | return ResponseEntity.ok(service.getEmployee(employeeId)); 30 | } 31 | 32 | //this method can be accessed by user whose role is admin 33 | @GetMapping 34 | @RolesAllowed("admin") 35 | public ResponseEntity> findALlEmployees() { 36 | return ResponseEntity.ok(service.getAllEmployees()); 37 | } 38 | 39 | public static void main(String[] args) { 40 | SpringApplication.run(SpringBootKeycloakExampleApplication.class, args); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/keycloak/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.keycloak.config; 2 | 3 | import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; 4 | import org.keycloak.adapters.springsecurity.KeycloakConfiguration; 5 | import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; 6 | import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Import; 10 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 11 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 12 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 13 | import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; 14 | import org.springframework.security.core.session.SessionRegistryImpl; 15 | import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; 16 | import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; 17 | 18 | @KeycloakConfiguration 19 | @EnableGlobalMethodSecurity(jsr250Enabled = true) 20 | @Import(KeycloakSpringBootConfigResolver.class) 21 | public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { 22 | /** 23 | * Registers the KeycloakAuthenticationProvider with the authentication manager. 24 | */ 25 | @Autowired 26 | public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 27 | KeycloakAuthenticationProvider authenticationProvider = new KeycloakAuthenticationProvider(); 28 | authenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); 29 | auth.authenticationProvider(authenticationProvider); 30 | } 31 | 32 | /** 33 | * Defines the session authentication strategy. 34 | */ 35 | @Bean 36 | @Override 37 | protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { 38 | return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); 39 | } 40 | 41 | @Override 42 | protected void configure(HttpSecurity http) throws Exception { 43 | super.configure(http); 44 | http 45 | .authorizeRequests() 46 | .anyRequest().permitAll(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/keycloak/entity/Employee.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.keycloak.entity; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.Id; 9 | 10 | @Entity 11 | @NoArgsConstructor 12 | @Data 13 | public class Employee { 14 | @Id 15 | @GeneratedValue 16 | private int id; 17 | private String name; 18 | private double salary; 19 | 20 | public Employee(String name, double salary) { 21 | this.name = name; 22 | this.salary = salary; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/keycloak/repository/EmployeeRepository.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.keycloak.repository; 2 | 3 | import com.javatechie.keycloak.entity.Employee; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface EmployeeRepository extends JpaRepository { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/keycloak/service/EmployeeService.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.keycloak.service; 2 | 3 | import com.javatechie.keycloak.entity.Employee; 4 | import com.javatechie.keycloak.repository.EmployeeRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.annotation.PostConstruct; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | import java.util.stream.Stream; 12 | 13 | @Service 14 | public class EmployeeService { 15 | 16 | @Autowired 17 | private EmployeeRepository employeeRepository; 18 | 19 | @PostConstruct 20 | public void initializeEmployeeTable() { 21 | employeeRepository.saveAll( 22 | Stream.of( 23 | new Employee("john", 20000), 24 | new Employee("mak", 55000), 25 | new Employee("peter", 120000) 26 | ).collect(Collectors.toList())); 27 | } 28 | 29 | public Employee getEmployee(int employeeId) { 30 | return employeeRepository 31 | .findById(employeeId) 32 | .orElse(null); 33 | } 34 | 35 | public List getAllEmployees() { 36 | return employeeRepository 37 | .findAll(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9090 3 | 4 | spring: 5 | h2: 6 | console: 7 | enabled: true 8 | 9 | keycloak: 10 | realm: javatechie 11 | auth-server-url: http://localhost:8180/auth 12 | resource: springboot-keycloak 13 | public-client: true 14 | bearer-only: true -------------------------------------------------------------------------------- /src/test/java/com/javatechie/keycloak/SpringBootKeycloakExampleApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.keycloak; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringBootKeycloakExampleApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------