微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何对Spring Security @PreAuthorize自定义表达式进行单元测试

如何解决如何对Spring Security @PreAuthorize自定义表达式进行单元测试

    @PostMapping
        @ResponseStatus(HttpStatus.CREATED)
        @PreAuthorize("@messageSecurityService.isAuthorized(#userAuthentication)")
        public void sendMessage(@AuthenticationPrincipal UserAuthentication userAuthentication,@RequestBody SendMessageRequest sendMessageRequest) {
                                              ......
     }

我想编写此端点的测试,但出现以下错误

 java.lang.IllegalArgumentException: Failed to evaluate expression '@messageSecurityService.isAuthorized(#userAuthentication)'
    at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:30)
    at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:59)
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.Vote(PreInvocationAuthorizationAdviceVoter.java:72)
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.Vote(PreInvocationAuthorizationAdviceVoter.java:40)
    at org.springframework.security.access.Vote.AffirmativeBased.decide(AffirmativeBased.java:63)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.cglibAopProxy$DynamicAdvisedInterceptor.intercept(cglibAopProxy.java:688)

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1058E: A problem occurred when trying to resolve bean 'messageSecurityService':'Could not resolve bean reference against beanfactory'
    at org.springframework.expression.spel.ast.BeanReference.getValueInternal(BeanReference.java:59)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:53)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:89)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:114)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:300)
    at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:26)
    ... 94 common frames omitted

Caused by: org.springframework.expression.AccessException: Could not resolve bean reference against beanfactory
    at org.springframework.context.expression.beanfactoryResolver.resolve(beanfactoryResolver.java:54)
    at org.springframework.expression.spel.ast.BeanReference.getValueInternal(BeanReference.java:55)
    ... 99 common frames omitted

Caused by: org.springframework.beans.factory.NoSuchBeanDeFinitionException: No bean named 'messageSecurityService' available
    at org.springframework.beans.factory.support.DefaultListablebeanfactory.getBeanDeFinition(DefaultListablebeanfactory.java:775)
    at org.springframework.beans.factory.support.Abstractbeanfactory.getMergedLocalBeanDeFinition(Abstractbeanfactory.java:1221)
    at org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:294)
    at org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:273)
    at org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:199)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105)
    at org.springframework.context.expression.beanfactoryResolver.resolve(beanfactoryResolver.java:51)
    ... 100 common frames omitted

如何使表达式解析bean?

使用 @MockBean MessageSecurityService无法正常工作。

解决方法

您是否已将@MockBean的返回结果存根存根

@MockBean(name = "messageSecurityService")
public MessageSecurityService messageSecurityService;

@Test
public void testing(){
 when(messageSecurityService.isAuthorized(anyString())).thenReturn("somethingHere");
 //rest of your assertions
}

还要在测试类中添加以下内容:

@BeforeEach
public void init() {
    MockitoAnnotations.initMocks(this);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。