我有一个非常简单的Spring Boot应用程序,资源位于/repositories
和/persons
。
这是我的build.gradle
文件。
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'
}
...
...
这是我的SecurityConfig.java
文件。
@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();
}
}
这是我的 application.yaml
文件。
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
所有内容都在我的本地机器上,Keycloak和Postgres是通过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
我在Keycloak中有两个用户“zemirco”和“one”,他们都有“user”角色。它们都可以很好地工作,路由“/persons”受到保护,而“/repositories”对所有人开放。
这是我的问题!我想保护单个资源,例如“/person/1”。但我无法使其正常工作:( 我已经尝试了几天,但没有成功。这是我的Keycloak设置。
这是我的策略。
这是资源。
这里是权限。 在Keycloak的评估过程中,一切都运作正常。然而,在我的Spring Boot应用程序中直接访问不起作用。尽管用户"one"应该只有访问权限,但我仍然可以使用"zemirco"访问"/person/1"。我现在有点迷失方向。你有任何想法吗?
非常感谢!
编辑于2021年1月10日
感谢大家的回答,但我仍认为在我的应用程序方面不需要太多额外的努力就可以实现(这一点尤其适用于政策执行者https://www.keycloak.org/docs/latest/authorization_services/#_enforcer_overview)。
PEP负责强制执行访问决策,这些决策是通过评估与受保护资源相关联的策略来做出的。它充当过滤器或拦截器,以检查基于这些决策授予的权限是否可以实现对受保护资源的特定请求。
这听起来正是我想要做的事情。不幸的是,我无法使其工作。我只是认为我的配置是错误的或者可能不完整。我将为这个问题添加奖励。