我有一个基于Spring Boot的应用程序,我们使用来自外部提供商的ISAM身份验证。我有一个rest / json端点/actuator/health
,它根据用户是否通过身份验证返回不同的数据。
如何在单元测试期间模拟身份验证以确保配置正确?
在setup()
中,我尝试手动设置令牌,并覆盖AuthorizationService以返回true。
@Before
public void setUp() throws Exception
{
mockMvc = webAppContextSetup(wac).apply(springSecurity()).build();
List roles = Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken("dave", "secret",
roles);
if (!auth.isAuthenticated()) { fail("NOT AUTHENTICATED!"); }
SecurityContextHolder.getContext().setAuthentication(auth);
//fake logged in
when(authorizationService.isCurrentUserAuthorized(anyString(),
anyString(),
ArgumentMatchers.any(ResourceType.class),
ArgumentMatchers.any(ActionType.class)))
.thenReturn(true);
}
但是,当我跑步时
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!auth.isAuthenticated()) { fail("NOT AUTHENTICATED!"); }
UsernamePasswordAuthenticationToken authToken =
(UsernamePasswordAuthenticationToken)auth;
mockMvc.perform(get("/health_secure")
.principal(auth)
.header("Authorization", "Bearer " + token))
.andDo(print())
.andExpect(status().isOk())
.andExpect(forwardedUrl("/actuator/health"));
我得到:
"error":"invalid_token","error_description":"Cannot convert access token to JSON"
答案正确here。由于Spring Security不会创建请求范围的bean,因此请自己创建一个bean并将其注入到需要的地方。这使您有机会自己模拟它。
这样的事情?:
@Service
@RequiredArgsConstructor
public class UserService {
public Principal getPrincipal() {
return SecurityContextHolder.getContext().getAuthentication();
}
public Optional<String> getCurrentLogin() {
Principal principal = getPrincipal();
if (principal == null)
return Optional.empty();
return Optional.ofNullable(principal.getName());
}
}
我的应用程序通过ISAM / OAuth2]进行身份验证
我希望只是覆盖AuthenticationManager
或OAuth2AuthenticationManager
我找到了一个较低级别的解决方案。
NOTE:
我很想在AuthenticationManager
级别查看解决方案。我必须重写ResourceServerTokenServices bean来模拟我的假Auth数据。
我在setAuth()
方法中添加了@Before
方法。
//"constants" for fake auth values private static final String user = "MyUser"; private static final String token = "MyTokenString"; //TokenServices to validate/convert ISAM Bearer Token @MockBean ResourceServerTokenServices tokenServices; private Authentication setAuth() throws Exception { UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, token, Collections.emptyList()); if (!auth.isAuthenticated()) { fail("NOT AUTHENTICATED!"); } SecurityContextHolder.getContext().setAuthentication(auth); DefaultOAuth2AccessToken mockTokenImpl = new DefaultOAuth2AccessToken(user); mockTokenImpl.setScope(Collections.singleton("authenticate:applications")); mockTokenImpl.setTokenType("Bearer"); when(tokenServices.readAccessToken(anyString())).thenReturn(mockTokenImpl); OAuth2Authentication oa2Auth = mock(OAuth2Authentication.class); when(oa2Auth.getPrincipal()).thenReturn(user); when(oa2Auth.getCredentials()).thenReturn(token); when(oa2Auth.getUserAuthentication()).thenReturn(auth); when(oa2Auth.isAuthenticated()).thenReturn(true); OAuth2Request oa2Req = mock(OAuth2Request.class); when(oa2Auth.getOAuth2Request()).thenReturn(oa2Req); when(tokenServices.loadAuthentication(anyString())).thenReturn(oa2Auth); return auth; }
此方法将
tokenServices
配置为具有使用Springsauthenticate()
类通过OAuth2AuthenticationManager伪造它的所有必要信息。