提问人:DLL 提问时间:9/15/2023 最后编辑:DLL 更新时间:11/1/2023 访问量:105
如何将安全上下文身份验证注入自定义 ConstraintValidator?
How to inject security context authentication into custom ConstraintValidator?
问:
在使用 Spring Boot 3 和 WebFlux 的 Kotlin 中,我有一个自定义验证器,它需要两个输入:一个是要验证的值,但我还需要身份验证主体来验证用户是否有权合法访问该值。
我在使用时得到一个.NullPointerException
getContext()
@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,在此示例中值为 a。PathParam
有人有解决这个问题的经验吗?
使用似乎不起作用,降低 Bean 优先级也不起作用。ReactiveSecurityContextHolder
答:
1赞
DLL
11/1/2023
#1
我们放弃了尝试在反应式/Webflux 配置上使用 ConstraintValidator。
我们最终使用了与大多数 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
...
评论
ReactiveSecurityContextHolder
SecurityContextHolder
ThreadLocal
Principal