在 Spring MVC 单元测试中模拟匿名身份验证
Simulate Anonymous Authentication in Spring MVC Unit Test
我正在尝试为来宾用户帐户编写单元测试。被测代码通过调用此方法检查来宾,在单元测试中 returns 来宾帐户为 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 容器中,匿名用户可以 returns AnonymousAuthenticationToken
的一个实例。因为容器环境和单元测试环境共享相同的安全配置class,假设安全配置可能是正确的。
下面的测试代码也适用于 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();
}
有谁知道如何在单元测试中模拟匿名身份验证令牌?
在运行测试前设置身份验证
@Before
public void setupAuthentication(){
SecurityContextHolder.getContext().setAuthentication(new AnonymousAuthenticationToken("GUEST","USERNAME", AuthorityUtils
.createAuthorityList("ROLE_ONE", "ROLE_TWO")));
}
在 Spring Security 4.1(尚未正式发布)中,我们引入了对 @WithAnonymousUser 的支持。
@WithAnonymousUser
支持是使用 @WithSecurityContext 构建的。这意味着您可以轻松地将支持添加到 4.0.x 中的代码库,直到 4.1.x 发布。要使其正常工作,您需要将以下 类 复制到您的测试源文件夹:
package org.springframework.security.test.context.support;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithSecurityContext(factory = WithAnonymousUserSecurityContextFactory.class)
public @interface WithAnonymousUser {}
package org.springframework.security.test.context.support;
import java.util.List;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
final class WithAnonymousUserSecurityContextFactory implements
WithSecurityContextFactory<WithAnonymousUser> {
public SecurityContext createSecurityContext(WithAnonymousUser withUser) {
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS");
Authentication authentication = new AnonymousAuthenticationToken("key", "anonymous", authorities);
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
return context;
}
}
然后你可以使用下面的方式运行作为一个匿名用户:
@Test
@WithAnonymousUser
public void testAnonymous() throws Exception {
// ...
}
注意:重要的是要注意,就像您需要为 @WithMockUser
做的一样,您需要确保使用 [=16] 设置 MockMvc
=] 作为 outlined in the reference.
我正在尝试为来宾用户帐户编写单元测试。被测代码通过调用此方法检查来宾,在单元测试中 returns 来宾帐户为 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 容器中,匿名用户可以 returns AnonymousAuthenticationToken
的一个实例。因为容器环境和单元测试环境共享相同的安全配置class,假设安全配置可能是正确的。
下面的测试代码也适用于 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();
}
有谁知道如何在单元测试中模拟匿名身份验证令牌?
在运行测试前设置身份验证
@Before
public void setupAuthentication(){
SecurityContextHolder.getContext().setAuthentication(new AnonymousAuthenticationToken("GUEST","USERNAME", AuthorityUtils
.createAuthorityList("ROLE_ONE", "ROLE_TWO")));
}
在 Spring Security 4.1(尚未正式发布)中,我们引入了对 @WithAnonymousUser 的支持。
@WithAnonymousUser
支持是使用 @WithSecurityContext 构建的。这意味着您可以轻松地将支持添加到 4.0.x 中的代码库,直到 4.1.x 发布。要使其正常工作,您需要将以下 类 复制到您的测试源文件夹:
package org.springframework.security.test.context.support;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithSecurityContext(factory = WithAnonymousUserSecurityContextFactory.class)
public @interface WithAnonymousUser {}
package org.springframework.security.test.context.support;
import java.util.List;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
final class WithAnonymousUserSecurityContextFactory implements
WithSecurityContextFactory<WithAnonymousUser> {
public SecurityContext createSecurityContext(WithAnonymousUser withUser) {
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS");
Authentication authentication = new AnonymousAuthenticationToken("key", "anonymous", authorities);
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
return context;
}
}
然后你可以使用下面的方式运行作为一个匿名用户:
@Test
@WithAnonymousUser
public void testAnonymous() throws Exception {
// ...
}
注意:重要的是要注意,就像您需要为 @WithMockUser
做的一样,您需要确保使用 [=16] 设置 MockMvc
=] 作为 outlined in the reference.