3

我正在尝试使用 Spring Security 和 Thymeleaf 为视图层编写 Spring MVC 集成测试。

就像文档中的所有示例一样,我已经使用 Spring Security Integration 设置了我的 MockMvc 对象。

集成测试设置:

import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;

    @Autowired 
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @Before
    public void setup() {

        mockMvc = MockMvcBuilders
                .webAppContextSetup(webApplicationContext)
                //.defaultRequest(get("/").with(user(someUser)))
                .apply(springSecurity())
                .build();
    }

Thymeleaf 配置为使用 SpringSecurityDialect。(thymeleaf-extras-springsecurity4)

 additionalDialects.add( new SpringSecurityDialect());

为了能够在视图层中使用 spring 安全表达式(示例)。

<p sec:authorize="hasRole('ROLE_USER')"> User logged in</p>

现在我的配置在测试之外工作得非常好,但是,当我尝试进行集成测试时,Thymeleaf 抛出一个异常,指出

(org.thymeleaf.extras.springsecurity4.auth.AuthUtils.class)

@SuppressWarnings("unchecked")
private static SecurityExpressionHandler<FilterInvocation> getExpressionHandler(final ServletContext servletContext) {

    final ApplicationContext ctx =
            WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);

    final Map<String, SecurityExpressionHandler> expressionHandlers =
            ctx.getBeansOfType(SecurityExpressionHandler.class);

    for (SecurityExpressionHandler handler : expressionHandlers.values()) {
        if (FilterInvocation.class.equals(GenericTypeResolver.resolveTypeArgument(handler.getClass(), SecurityExpressionHandler.class))) {
            return handler;
        }
    }

    throw new TemplateProcessingException(
            "No visible SecurityExpressionHandler instance could be found in the application " +
            "context. There must be at least one in order to support expressions in Spring Security " +
            "authorization queries.");

此异常是有效的,因为在集成测试期间应用程序上下文中缺少 SecurityExpressionHandler.class。

所以我的问题是......为什么 SecurityExpressionHandler.class 在常规 servlet 环境中注册为 spring bean,但是在使用集成测试配置时,上下文中缺少 ctx.getBeansOfType(SecurityExpressionHandler.class)?这是 Spring Security 中的错误吗?或者我是否需要添加额外的逻辑来为集成测试注册一个 SecurityExpressionHandler bean?

我尝试通过扩展 GlobalMethodSecurityConfiguration 和 @Overriding createExpressionHandler() 并将其添加到我的测试配置来“强制创建”一个 SecurityExpressionHandler,但该 bean 仍然没有在 WebApplicationContext 中注册。

这对我来说现在是一个障碍,因为我无法对包含嵌入其中的 Spring Security 表达式的任何视图文件执行任何集成测试。

Spring v4.1.6
Spring Security 4.0.1
Thymeleaf v2.1.4
4

1 回答 1

0

如果您正在WebApplicationContext使用 加载测试@ContextHierarchy,那么这将不适用于 Spring Framework 4.1.4 到 4.1.6,因为已确认的错误将在 4.1.7 中修复。

有关详细信息,请参阅SPR-13075

于 2015-06-04T01:43:15.433 回答