Spring Security DefaultMethodSecurityExpressionHandler bean未注册为Integration Test的默认Spring Security配置 [英] Spring security DefaultMethodSecurityExpressionHandler bean is not registered for Integration Test's default spring security config

查看:691
本文介绍了Spring Security DefaultMethodSecurityExpressionHandler bean未注册为Integration Test的默认Spring Security配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用Spring Security和Thymeleaf为视图层编写Spring MVC集成测试.

I am attempting to write Spring MVC integration test with Spring Security and Thymeleaf for the view layer.

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

I have setup my MockMvc object with Spring Security Integration just like all the examples from the documentation.

集成测试设置:

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)

Thymeleaf is configured to utilize the SpringSecurityDialect. (thymeleaf-extras-springsecurity4)

 additionalDialects.add( new SpringSecurityDialect());

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

For the purpose of being able to utilize spring security expressions in the view layer (example).

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

现在,在测试之外,我的配置仍然可以正常运行,但是,当我尝试进行集成测试时,Thymeleaf抛出了一个异常,表明

Now my configuration works perfectly fine outside of testing however, when I try to make an integration test Thymeleaf throws an exception stating that

(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.

This exception is valid because SecurityExpressionHandler.class is missing from the application context during the integration test.

所以我的问题是 ......为什么在常规Servlet环境中将SecurityExpressionHandler.class注册为spring bean,但是在使用集成测试配置ctx.getBeansOfType(SecurityExpressionHandler.class)时却丢失了从上下文?这是Spring Security中的错误吗?还是我需要添加其他逻辑以仅为集成测试注册SecurityExpressionHandler bean?

So my question is... how come a SecurityExpressionHandler.class is registered as spring bean in a regular servlet environment but when using the Integration Test config ctx.getBeansOfType(SecurityExpressionHandler.class) is missing from the context? Is this a bug in Spring Security? Or do I need to add additional logic to register a SecurityExpressionHandler bean for the integration test only?

我试图通过扩展GlobalMethodSecurityConfiguration和@Overriding createExpressionHandler()并将其添加到我的测试配置中来强制创建"一个SecurityExpressionHandler,但是该bean尚未在WebApplicationContext中注册.

I tried to "force create" a SecurityExpressionHandler by extending GlobalMethodSecurityConfiguration and @Overriding the createExpressionHandler() and adding it to my test config but still the bean was not registered with the WebApplicationContext.

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

This is a blocker for me right now because I cannot perform any integration testing on any view file that contains Spring Security expressions embedded inside them.

Spring v4.1.6
Spring Security 4.0.1
Thymeleaf v2.1.4

推荐答案

如果您正在使用@ContextHierarchy加载WebApplicationContext进行测试,则由于以下原因,它不适用于Spring Framework 4.1.4至4.1.6.已确认的错误,将在4.1.7中修复.

If you are loading the WebApplicationContext for your test using @ContextHierarchy, then this will not work with Spring Framework 4.1.4 through 4.1.6 due to a confirmed bug that will be fixed in 4.1.7.

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

See SPR-13075 for details.

这篇关于Spring Security DefaultMethodSecurityExpressionHandler bean未注册为Integration Test的默认Spring Security配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆