首页 > 解决方案 > 未调用自定义 ReactiveJwtAuthenticationConverterAdapter

问题描述

具有显式角色的页面得到 403,并且我的自定义 JwtAuthenticationConverter 没有被调用。怎么来的?

我使用 keycloak 作为 oauth2 提供程序,并且我使用 oauth2Login 来提示登录页面。我使用与spring文档中相同的代码。

package com.eLoomina.gateway.security

import org.slf4j.LoggerFactory
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.convert.converter.Converter
import org.springframework.security.authentication.AbstractAuthenticationToken
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
import org.springframework.security.config.web.server.ServerHttpSecurity
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.oauth2.jwt.Jwt
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter
import org.springframework.security.web.server.SecurityWebFilterChain
import reactor.core.publisher.Mono
import java.util.stream.Collectors


@Configuration
@EnableWebFluxSecurity
class SecurityConfig {
    companion object {
        @Suppress("JAVA_CLASS_ON_COMPANION")
        @JvmStatic
        private val logger = LoggerFactory.getLogger(javaClass.enclosingClass)
    }

    @Bean
    @Throws(Exception::class)
    fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        http.authorizeExchange()
                .pathMatchers("/login", "/").permitAll()
                .pathMatchers("/login/with-role").hasRole("populate")
                .anyExchange().authenticated()
                .and()
                .oauth2Login().and()
                .oauth2ResourceServer().jwt().jwtAuthenticationConverter(grantedAuthoritiesExtractor())
        return http.build()
    }

    fun grantedAuthoritiesExtractor(): Converter<Jwt, Mono<AbstractAuthenticationToken>> {
        val extractor = KeycloakRealmRoleConverter()
        return ReactiveJwtAuthenticationConverterAdapter(extractor)
    }

    class KeycloakRealmRoleConverter : JwtAuthenticationConverter() {
        override fun extractAuthorities(jwt: Jwt): Collection<GrantedAuthority> {
            val realmAccess = jwt.claims["realm_access"] as Map<String, Any>
            logger.info("code not reached")
            return (realmAccess["roles"] as List<String>).stream()
                    .map { roleName: String -> "ROLE_${roleName.toUpperCase()}" } // prefix to map to a Spring Security "role"
                    .map { role: String? -> SimpleGrantedAuthority(role) }
                    .collect(Collectors.toList())
        }
    }
}

标签: springspring-bootkotlinspring-webfluxspring-security-oauth2

解决方案


推荐阅读