├── 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 |
--------------------------------------------------------------------------------