我正在尝试使用 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