Spring security DefaultMethodSecurityExpressionHandler bean 未注册 Integration Test 的默认 spring security
Posted
技术标签:
【中文标题】Spring security DefaultMethodSecurityExpressionHandler bean 未注册 Integration Test 的默认 spring security 配置【英文标题】:Spring security DefaultMethodSecurityExpressionHandler bean is not registered for Integration Test's default spring security config 【发布时间】:2015-08-17 06:04:23 【问题描述】:我正在尝试使用 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
【问题讨论】:
降级到 Spring v4.1.3 “修复”了这个问题......这让我怀疑这是一个错误。 【参考方案1】:如果您使用 @ContextHierarchy
为您的测试加载 WebApplicationContext
,那么这将不适用于 Spring Framework 4.1.4 到 4.1.6,因为已确认的错误将在 4.1.7 中修复。
详情请见SPR-13075。
【讨论】:
以上是关于Spring security DefaultMethodSecurityExpressionHandler bean 未注册 Integration Test 的默认 spring security的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security:2.4 Getting Spring Security
没有 JSP 的 Spring Security /j_spring_security_check
Spring Security 登录错误:HTTP 状态 404 - /j_spring_security_check