如何用自定义bean spel测试@preauthorize是否有效?

bmp9r5qi  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(410)

我有很多 @RestController 使用以下方法:

@PreAuthorize("@myBean.myMethod(#param1, #param2)")
public void foo(String param1, Long param2) {}

在什么地方

@Component
public class MyBean {
    public boolean myMethod(String param1, Long param2) {

        return importantSecurityCheck();
    }
}

它工作得很好,但我想避免重构后可能出现的愚蠢错误(因为据我所知,spring在调用方法之前不会检测到错误),所以我的想法是编写一个测试来检查表达式是否有效(例如,参数具有相同的类型和名称是否有效)。
我试着这样做:

@Test
public void checkSecurityExpressions() {
 Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(RestController.class);

    beansWithAnnotation.forEach((name, bean) -> {
        Method[] methods = AopUtils.getTargetClass(bean).getMethods();

        for (Method method : methods) {
            PreAuthorize annotation = method.getAnnotation(PreAuthorize.class);

            if (annotation != null) {

                String securityExpression = annotation.value();

                System.out.println(securityExpression);
            }

        }
    });
}

很好地找到了表达方式,但是 ExpressionParser 我发现使用更简单表达式的示例(没有安全上下文,甚至没有 @ 一开始)。
如何检查它的正确性?或者有更好的解决方法?

6ss1mwsb

6ss1mwsb1#

最近我不得不写一个这样的测试用例来回答另一个堆栈溢出问题。
鉴于:

public class Foo {

    public boolean isOk(String param) {
        return "good".equals(param);
    }

    @PreAuthorize("@foo.isOk(#param1)")
    public String bar(String param1) {
        return "authOk";
    }

}

还有一个测试 @Configuration 那是什么 extends GlobalAuthenticationConfigurerAdapter :

@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("foo").password("bar").roles("admin");
}

然后:

@Autowired
private Foo foo;

@Test
public void test() {
    SecurityContext ctx = SecurityContextHolder.createEmptyContext();
    ctx.setAuthentication(new UsernamePasswordAuthenticationToken("foo", "bar"));
    SecurityContextHolder.setContext(ctx);
    assertThat(foo.bar("good")).isEqualTo("authOk");
    try {
        foo.bar("bad");
        fail("Expected AccessDeniedException");
    }
    catch (AccessDeniedException e) {
        // expected
    }
}

将验证您的 @PreAuthorize 斯皮尔。

相关问题