I've got a very simple Spring Boot application with resources at /repositories and /persons.
Here is my build.gradle file.
plugins {
id 'org.springframework.boot' version '2.4.0'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
// use java 11 until keycloak is fixed
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencyManagement {
imports {
mavenBom "org.keycloak.bom:keycloak-adapter-bom:12.0.1"
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.keycloak:keycloak-spring-boot-starter'
implementation 'org.flywaydb:flyway-core'
runtime 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
...
...
Here is my SecurityConfig.java file.
@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
var keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.antMatchers("/persons*")
.hasRole("user")
.anyRequest()
.permitAll();
}
@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
Here is my application.yaml file.
spring:
datasource:
url: jdbc:postgresql://localhost:5432/postgres
username: john
password: john
keycloak:
auth-server-url: http://localhost:8081/auth/
realm: myrealm
resource: myclient
credentials:
secret: 45d43bd6-5ab9-476c-83c8-67bd203a78ee
It's all on my local machine and Keycloak and Postgres are started via docker compose.
version: "3.1"
volumes:
postgres_data:
driver: local
services:
db:
image: "postgres:13.1"
ports:
- "5432:5432"
environment:
POSTGRES_DB: postgres
POSTGRES_USER: john
POSTGRES_PASSWORD: john
postgres:
image: "postgres:13.1"
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
keycloak:
image: quay.io/keycloak/keycloak:12.0.1
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: Pa55w0rd
ports:
- 8081:8080
depends_on:
- postgres
I've got the users zemirco and one in Keycloak and they both have the user role. It all works very nicely and the route /persons is protected whereas /repositories is open for all.
Here is my problem! I'd like to secure individual resources, e.g. /person/1. I cannot make it work :( I've been trying for days now but no luck. Here are my keycloak settings.
Here is my policy.
Here is the resource.
Here is the permission.
It all works during the evaluating at Keycloak. However it does not work directly at my Spring Boot application. I can still access /person/1 as zemirco although user one should only have access.
I'm a bit lost at the moment. Do you have any ideas?
Thank you very much!
Edit Jan 10 2021
Thank you all for your answers but I still think it's doable without a lot of extra effort on my side (the application side). I'm especially looking at policy enforcers https://www.keycloak.org/docs/latest/authorization_services/#_enforcer_overview.
A PEP is responsible for enforcing access decisions from the Keycloak server where these decisions are taken by evaluating the policies associated with a protected resource. It acts as a filter or interceptor in your application in order to check whether or not a particular request to a protected resource can be fulfilled based on the permissions granted by these decisions.
This sound exactly like what I'm trying to do. Unfortunately I cannot make it work. I just think my configuration is false or maybe incomplete. I will add a bounty to the question.


