Spring 6 升级@PreAuthorize 无法与 ArgumentResolver 一起使用

问题描述 投票:0回答:1

我正在对 Spring 6 升级进行一些测试,当我们升级到具有公共访问模式的环境时,PreAuthorize 装饰器失败。

  1. 用户提交带有保存请求的表单。
  2. /save 端点有一个 @PreAuthorize 装饰器,它使用辅助方法 AuthorizationHelper.IS_STATUS_VALID
  3. 端点还在 PreAuthorize 装饰器中使用的方法签名中指定一个对象,该对象由自定义 ArgumentResolver 解析。代码看起来像这样
    @PreAuthorize("hasAnyAuthority('IS_APPLICANT', 'IS_ADMIN') and " + AuthorizationHelper.IS_STATUS_VALID)
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String save(@ModelAttribute SomeModel sm, WebRequest request,
            HttpSession session, AuthorizationDto authDto) {
          // do page logic
          return some page view;
     }

我已确认 ArgumentResolver 已正确注册,并且 authDto 已正确初始化。在这一环境中,当通过我认为是 Spring SpEl 表达式调用 AuthorizationHelper isStatusValid 方法时,authDto 为 null。我是这个应用程序的新手,正在寻求一些帮助来了解为什么会发生这种情况。我的研究表明这可能是环境配置的问题,但我想知道我在寻找什么失败。这就是 AuthorizationHelper 代码的样子。

@Component
public class AuthorizationHelper {
    // constructor
    @Autowired
    public AuthorizationHelper(){
     // init any services needed
    }

    public static final String IS_STATUS_VALID = "@authorizationHelper.isStatusValid(#authDto)";

    public boolean isStatusValid(AuthorizationDto authDto) {
        logger.info("AuthorizationHelper :: authDto: " + authDto); // is null
        // do logic
        return result;
    }

}

为了更好地衡量,我也会发布请求解析器代码,尽管我已经确认这是有效的。

@Component("authResolver")
public class CustomAuthorizationResolver implements HandlerMethodArgumentResolver {

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
        NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        AuthorizationDto authDto = new AuthorizationDto();
        // some logic
        logger.info("AuthorizationDto after setting properties: {}", authDto); // not null. is invoked when the /save endpoint is hit, before the PreAuthorize code is executed
        return authDto;
    }
}

再次,我将开始深入研究任何环境配置差异。我知道的最重要的一点是此环境具有与开发环境不同的访问模式。我的初步研究表明这可能是一个代理问题。我很感激任何帮助! 这是堆栈跟踪的相关片段

java.lang.NullPointerException: Cannot invoke "org.example.app.dto.AuthorizationDto.doSomeValidation()" because "authDto" is null
at org.example.app.web.helpers.AuthorizationHelper.isStatusValid(AuthorizationHelper.java:49)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:142)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:125)
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:401)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:97)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:222)
at org.springframework.expression.spel.ast.OpAnd.getBooleanValue(OpAnd.java:57)
at org.springframework.expression.spel.ast.OpAnd.getValueInternal(OpAnd.java:52)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:119)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:309)
at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:30)
at org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager.check(PreAuthorizeAuthorizationManager.java:68)
at org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager.check(PreAuthorizeAuthorizationManager.java:40)
at org.springframework.security.config.annotation.method.configuration.DeferringObservationAuthorizationManager.check(DeferringObservationAuthorizationManager.java:47)
at org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor.attemptAuthorization(AuthorizationManagerBeforeMethodInterceptor.java:251)
at org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor.invoke(AuthorizationManagerBeforeMethodInterceptor.java:197)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720)
at org.example.app.web.controllers.ApplicantController$$SpringCGLIB$$0.save(<generated>)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(D
spring-mvc spring-security spring-aop spring-expression
1个回答
0
投票

问题是我们的新遗物罐需要更新。它与我们所做的其他春季更新不兼容,并且我们没有在较低的环境中使用它。

© www.soinside.com 2019 - 2024. All rights reserved.