我是Spring和Lombok岛的新手。我正在为一个控制器进行单元测试,其中方法使用@AuthenticationPrincipal。根据我所读到的,它将经过身份验证的用户的信息传递到方法中。有没有办法在单元测试中模拟这个?
@AuthenticationPrincipal
aamkag611#
最简单的解决方案是@WithMockUser。它做你要求的。但是,如果您对它不满意,您可以创建一个注解并根据您的需要对其进行调整。我假设你已经尝试过@WithMockUser,它真的不符合你的需要。有三项重要任务。第一步是 * 创建一个注解 *,然后创建一个表示系统的 * 用户 * 的类,最后创建 SecurityContextFactory。1.让我们从注解开始
@WithMockUser
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import org.springframework.security.test.context.support.WithSecurityContext; @Retention(RetentionPolicy.RUNTIME) @WithSecurityContext(factory = WithMockAaronSecurityContextFactory.class) public @interface WithAaronUser { String username() default "TestUser"; String[] roles() default { "ROLE_ADMIN" }; }
字符串1.模拟用户类
import java.util.Collection; import java.util.stream.Collectors; import java.util.stream.Stream; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; public class MockUserDetails { private String username; private Collection<? extends GrantedAuthority> authorities; public MockUserDetails(String username, String[] roles) { this.username = username; this.authorities = Stream.of(roles) .map(role -> new SimpleGrantedAuthority(role)).collect(Collectors.toSet()); } public String getUsername() { return username; } public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; } }
型3最后是 SecurityContextFactory。请注意,该实现使用与@WithMockUser相同的工厂类(WithSecurityContextFactory)。
WithSecurityContextFactory
import java.io.Serializable; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 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; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; import org.springframework.security.test.context.support.WithSecurityContextFactory; public class WithMockAaronSecurityContextFactory implements WithSecurityContextFactory<WithAaronUser> { @Override public SecurityContext createSecurityContext(WithAaronUser user) { MockUserDetails principal = new MockUserDetails(user.username(), user.roles()); MockHttpServletRequest request = new MockHttpServletRequest(); request.setServerName("www.example.com"); request.setRequestURI("/token"); request.setQueryString("param1=value1¶m"); request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, "mocked_token"); OAuth2AuthenticationDetails authDetails = new OAuth2AuthenticationDetails(request); Map<String, String> decodedDetails = new HashMap<>(); decodedDetails.put("first_name", "Jean-Claude"); decodedDetails.put("last_name", "Van Damme"); authDetails.setDecodedDetails(decodedDetails); UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(principal.getUsername(), "password", principal.getAuthorities()); auth.setDetails(authDetails); List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ADMIN"); OAuth2Request oAuth2Request = new OAuth2Request(Collections.emptyMap(), "", authorities, true, Collections.emptySet(), Collections.emptySet(), "http://somethig.com", Collections.emptySet(), Collections.emptyMap()); OAuth2Authentication oAuth = new OAuth2Authentication(getOauth2Request(), auth); oAuth.setDetails(authDetails); SecurityContext context = SecurityContextHolder.createEmptyContext(); context.setAuthentication(oAuth); return context; } }
型
1条答案
按热度按时间aamkag611#
最简单的解决方案是
@WithMockUser
。它做你要求的。但是,如果您对它不满意,您可以创建一个注解并根据您的需要对其进行调整。我假设你已经尝试过
@WithMockUser
,它真的不符合你的需要。有三项重要任务。第一步是 * 创建一个注解 *,然后创建一个表示系统的 * 用户 * 的类,最后创建 SecurityContextFactory。
1.让我们从注解开始
字符串
1.模拟用户类
型
3最后是 SecurityContextFactory。请注意,该实现使用与
@WithMockUser
相同的工厂类(WithSecurityContextFactory
)。型