java - 如何测试带有自定义 bean-spel 的 @PreAuthorize 是否有效?

标签 java spring spring-security annotations spring-el

我有很多 @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 示例都可以使用更简单的表达式(没有安全上下文,甚至在开头没有 @)。

如何检查其正确性?或者也许这个问题有更好的解决方案?

最佳答案

我最近不得不写一个这样的测试用例到 answer another stack overflow question .

给定:

public class Foo {

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

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

}

和测试 @Configurationextends 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 SpEL。

关于java - 如何测试带有自定义 bean-spel 的 @PreAuthorize 是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47045671/

相关文章:

java - 通过大津法的 "slower version"计算阈值

java - Netbeans Java 桌面数据库应用程序,具有从 mysql 连接到用户的登录名

java - hibernate 一对一映射不更新子表

java - 为什么 j_spring_security_check 404?

java - 如何在 Web API 中使用 Spring Security?

java - 无法通过 Windows 10 和 DLINK DIR-615 路由器中的 Java 代码获取 DNS 请求

Java HttpURLConnection 使用 SOCKS 代理而不是 HTTP

java - 是否可以在没有应用程序服务器的情况下运行 Spring?

spring - 原因 : No AuthenticationProvider found for org. springframework.security.authentication.UsernamePasswordAuthenticationToken

spring-security - 使用Postman测试 Spring 安全性