Spring security 在Spring MVC单元测试中模拟匿名身份验证

Spring security 在Spring MVC单元测试中模拟匿名身份验证,spring-security,spring-test,spring-test-mvc,Spring Security,Spring Test,Spring Test Mvc,我正在尝试为来宾用户帐户编写单元测试。测试中的代码通过调用此方法检查来宾帐户,该方法在单元测试中为来宾帐户返回null /** * Determines if the user is a guest account. * * @return True if the account is guest account, false otherwise. */ public boolean isGuest() { Authentication auth = SecurityContex

我正在尝试为来宾用户帐户编写单元测试。测试中的代码通过调用此方法检查来宾帐户,该方法在单元测试中为来宾帐户返回null

/**
 * Determines if the user is a guest account.
 *
 * @return True if the account is guest account, false otherwise.
 */
public boolean isGuest() {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null) {
        if (auth instanceof AnonymousAuthenticationToken) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}
在服务器Tomcat容器中,匿名用户可以返回
AnonymousAuthenticationToken
的实例。因为容器环境和单元测试环境都共享相同的安全配置类,所以假设安全配置可能是正确的

下面的测试代码也适用于
MockUser
,因此我认为安全测试配置可能还可以:

@Test
@WithMockUser(username="Test.Customer.1@mailinator.com", roles = {"ADMIN"})
public void testCheckoutPage() throws Exception{
    logger.entry();
    String targetView = OrderViews.convertViewReference(getPageDirectory(), OrderViews.CHECKOUT_LOGIN_PAGE, false);
    String targetUrl = "/checkout";

    Order order = OrderBuilder.buildSampleGuestOrder(OrderStatus.NEW, 5);
    prepareMocks(order);
    Map<String, Object> sessionAttrs = new HashMap<>();
    sessionAttrs.put(OrderConstants.OPEN_ORDER_ID_ATTRIBUTE, order.getId());

    this.mockMvc.perform(get(targetUrl).sessionAttrs(sessionAttrs))
            .andExpect(status().isOk())
            .andExpect(view().name(targetView))
            .andExpect(model().attribute("order", order))
            .andExpect(model().attributeExists("loginForm"));


    this.mockMvc.perform(MockMvcRequestBuilders.post(targetUrl))
            .andExpect(status().isMethodNotAllowed());

    logger.exit();
}
@测试
@WithMockUser(username=“Test.Customer。1@mailinator.com,角色={“管理员”})
public void testCheckoutPage()引发异常{
logger.entry();
字符串targetView=OrderViews.convertViewReference(getPageDirectory(),OrderViews.CHECKOUT\u LOGIN\u PAGE,false);
字符串targetUrl=“/checkout”;
Order Order=OrderBuilder.buildSampleGuestOrder(OrderStatus.NEW,5);
准备邮件(订单);
Map sessionatrs=newhashmap();
sessionatrs.put(orderstants.OPEN_ORDER_ID_属性,ORDER.getId());
this.mockMvc.perform(get(targetUrl).sessionatrs(sessionatrs))
.andExpect(状态().isOk())
.andExpect(视图().name(targetView))
.andExpect(model().attribute(“order”,order))
.andExpect(model().attributeExists(“loginForm”);
this.mockMvc.perform(MockMvcRequestBuilders.post(targetUrl))
.andExpect(状态().isMethodNotAllowed());
logger.exit();
}

有人知道如何在单元测试中模拟匿名身份验证令牌吗?

在运行测试之前设置身份验证

@Before
public void setupAuthentication(){
    SecurityContextHolder.getContext().setAuthentication(new AnonymousAuthenticationToken("GUEST","USERNAME", AuthorityUtils
            .createAuthorityList("ROLE_ONE", "ROLE_TWO")));
}
在SpringSecurity4.1(还不是GA)中,我们引入了对的支持

@WithAnonymousUser
支持是使用构建的。这意味着在4.1.x发布之前,您可以轻松地在4.0.x中添加对代码库的支持。要使其工作,您需要将以下类复制到测试源文件夹:

package org.springframework.security.test.context.support;
导入java.lang.annotation.Documented;
导入java.lang.annotation.ElementType;
导入java.lang.annotation.Inherited;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
导入java.lang.annotation.Target;
导入org.springframework.security.authentication.AnonymousAuthenticationToken;
导入org.springframework.security.core.context.SecurityContext;
@目标({ElementType.METHOD,ElementType.TYPE})
@保留(RetentionPolicy.RUNTIME)
@继承的
@记录
@WithSecurityContext(工厂=WithAnonymousUserSecurityContextFactory.class)
具有匿名用户{}的公共@接口
package org.springframework.security.test.context.support;
导入java.util.List;
导入org.springframework.security.authentication.AnonymousAuthenticationToken;
导入org.springframework.security.core.Authentication;
导入org.springframework.security.core.GrantedAuthority;
导入org.springframework.security.core.authority.AuthorityUtils;
导入org.springframework.security.core.context.SecurityContext;
导入org.springframework.security.core.context.SecurityContextHolder;
使用AnonymousUserSecurityContextFactory实现的最终类
使用安全上下文工厂{
public SecurityContext createSecurityContext(WithAnonymousUser withUser){
列表权限=AuthorityUtils.createAuthorityList(“角色_匿名”);
身份验证=新的匿名身份验证令牌(“密钥”、“匿名”、权限);
SecurityContext上下文=SecurityContextHolder.createEmptyContext();
setAuthentication(身份验证);
返回上下文;
}
}
然后,您可以使用以下命令作为匿名用户运行:

@测试
@匿名用户
public void testAnonymous()引发异常{
// ...
}

注意:重要的是要注意,正如您需要为
@with mockuser
所做的一样,您需要确保使用
apply(springSecurity())
as设置
MockMvc

谢谢Rob,前面的答案很好,所以我会一直坚持到4.1发布。干杯