Spring Boot 如何将安全上下文身份验证注入到自定义约束验证器中?

q9yhzks0  于 7个月前  发布在  Spring
关注(0)|答案(1)|浏览(95)

在使用Sping Boot 3和WebFlux的Kotlin中,我有这个自定义验证器,它需要两个输入:一个是正在验证的值,但我还需要身份验证主体来验证用户是否可以合法访问该值。
我在使用getContext()时得到一个NullPointerException

@Component
class OrgInstanceValidator(val validator: OrgPermissionValidator) : ConstraintValidator<ValidOrgInstance, InstanceId> {

    override fun isValid(value: InstanceId, context: ConstraintValidatorContext): Boolean = runBlocking {
        val accessToken = ReactiveSecurityContextHolder.getContext().map(SecurityContext::getAuthentication).map {
            it.principal as Jwt
        }.awaitSingle()
        validator.validateInstanceAccess(accessToken.subject, value).awaitSingle()
    }.isGranted
}

字符串
我也接受在控制器上使用AOP,在这个例子中,值是PathParam
有人有解决这个问题的经验吗?
使用ReactiveSecurityContextHolder似乎不起作用,降低bean优先级也不起作用。

csbfibhn

csbfibhn1#

我们放弃了在React式/Webflux配置上使用约束验证器的尝试。
我们最终使用了与大多数RestController注解(如AuthenticationPrincipal,PathVariable等)相同的机制,通过创建我们自己的注解并为处理注解类的HandlerMethodArgumentResolver类型创建bean:

import org.springframework.web.reactive.HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE
import java.security.Principal
...

class MethodAnnotationValidator<T : Annotation>(
    adapterRegistry: ReactiveAdapterRegistry,
    private val annotation: Class<T>,
    private val validator: (Principal, String) -> Mono<Any>,
) : HandlerMethodArgumentResolver {

    // compose this resolver to fetch the Auth context
    private val principal = PrincipalMethodArgumentResolver(adapterRegistry)

    // path var resolver isn't composable, next best thing
    private val pathParam = { paramName: String, exchange: ServerWebExchange -> exchange
        .getAttributeOrDefault(URI_TEMPLATE_VARIABLES_ATTRIBUTE, emptyMap<Any, Any>())
        .get(paramName)!!}
    
   // resolve Principal and PathParam and call validator() 
   // inside resolveArgument() override
...

字符串

相关问题