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

q9yhzks0  于 2023-11-17  发布在  Spring
关注(0)|答案(1)|浏览(153)

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

  1. @Component
  2. class OrgInstanceValidator(val validator: OrgPermissionValidator) : ConstraintValidator<ValidOrgInstance, InstanceId> {
  3. override fun isValid(value: InstanceId, context: ConstraintValidatorContext): Boolean = runBlocking {
  4. val accessToken = ReactiveSecurityContextHolder.getContext().map(SecurityContext::getAuthentication).map {
  5. it.principal as Jwt
  6. }.awaitSingle()
  7. validator.validateInstanceAccess(accessToken.subject, value).awaitSingle()
  8. }.isGranted
  9. }

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

csbfibhn

csbfibhn1#

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

  1. import org.springframework.web.reactive.HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE
  2. import java.security.Principal
  3. ...
  4. class MethodAnnotationValidator<T : Annotation>(
  5. adapterRegistry: ReactiveAdapterRegistry,
  6. private val annotation: Class<T>,
  7. private val validator: (Principal, String) -> Mono<Any>,
  8. ) : HandlerMethodArgumentResolver {
  9. // compose this resolver to fetch the Auth context
  10. private val principal = PrincipalMethodArgumentResolver(adapterRegistry)
  11. // path var resolver isn't composable, next best thing
  12. private val pathParam = { paramName: String, exchange: ServerWebExchange -> exchange
  13. .getAttributeOrDefault(URI_TEMPLATE_VARIABLES_ATTRIBUTE, emptyMap<Any, Any>())
  14. .get(paramName)!!}
  15. // resolve Principal and PathParam and call validator()
  16. // inside resolveArgument() override
  17. ...

字符串

展开查看全部

相关问题