【问题标题】:Springboot with Keycloak always return 403带有 Keycloak 的 Springboot 总是返回 403
【发布时间】:2021-11-13 03:28:48
【问题描述】:

按照本教程Baeldung,我已经使用 Keycloak 创建了一个 Springboot 应用程序 当我尝试输入 /api/foos 时,它总是返回 403 而没有任何错误消息。

// SecurityConfig
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
class SecurityConfig(
    private val unauthorizedHandler: JwtAuthenticationEntryPoint
) : WebSecurityConfigurerAdapter() {
    @Throws(Exception::class)
    override fun configure(http: HttpSecurity) {
        http
            .cors()
            .and()
            .csrf()
            .disable()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .exceptionHandling()
            .authenticationEntryPoint(unauthorizedHandler)
            .and()
            .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/user/info", "/api/foos/**", "/api/foos")
            .hasAnyRole("free_user")
            .antMatchers(HttpMethod.POST, "/api/foos")
            .hasAnyRole("free_user")
            .anyRequest()
            .authenticated()
            .and()
            .oauth2ResourceServer()
            .jwt()
    }
}


// Controller
@RestController
@RequestMapping(value = ["/api/foos"])
class SecurityTestController() {

    @GetMapping(value = ["/{id}"])
    fun findOne(@PathVariable id: Long?): String {
        return "fineOne with id $id"
    }

    @GetMapping
    fun findAll(): Message {
        return Message("findAll")
    }
}


// application.properties
# Resource server config
rest.security.issuer-uri=http://localhost:8081/auth/realms/dev
spring.security.oauth2.resourceserver.jwt.issuer-uri=${rest.security.issuer-uri}
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=${rest.security.issuer-uri}/protocol/openid-connect/certs


// build.gradle (app)
plugins {
     id("org.springframework.boot")
}
dependencies {
    implementation("org.springframework.boot:spring-boot-starter- oauth2-resource-server")
    implementation("org.springframework.boot:spring-boot-starter-security")
    testImplementation("org.springframework.security:spring-security-test")
}

这是我在 Keycloak 上的用户

邮递员结果:

我已经尝试过的

  1. 禁用 csrf - 不工作
  2. 评论 SecurityConfig 类 - 在没有安全性的情况下工作

【问题讨论】:

    标签: spring-boot keycloak keycloak-rest-api


    【解决方案1】:

    看起来“free_user”是一个客户角色。

    两种解决方案:

    要么删除当前的“free_user”客户端角色,在全局角色选项卡中创建一个“free_user”领域角色,然后将其分配给您的用户。

    或者,将属性 keycloak.use-resource-role-mappings=true 添加到您的 Spring 引导配置中,以允许 Spring Security 映射您当前的客户端角色。

    【讨论】:

    • 还是不行。我需要添加更多依赖项吗?我已将 build.gradle(app) 添加到我的帖子中。
    【解决方案2】:

    我在这里找到了答案LINK

    我们需要在 Spring 安全和 Keycloak 角色之间创建自定义映射。

    public class KeycloakRealmRoleConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
    @Override
    public Collection<GrantedAuthority> convert(Jwt jwt) {
        final Map<String, Object> realmAccess = (Map<String, Object>) jwt.getClaims().get("realm_access");
        return ((List<String>)realmAccess.get("roles")).stream()
                .map(roleName -> "ROLE_" + roleName) // prefix to map to a Spring Security "role"
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-04-03
      • 2019-05-15
      • 2017-09-28
      • 2020-02-06
      • 2015-12-23
      • 2018-08-15
      • 2018-04-29
      • 1970-01-01
      • 2016-04-22
      相关资源
      最近更新 更多