我需要写一个jUnit测试用例,它总是因为“/contextpath/oauth2/token?grant_type=password”。
@RunWith(SpringRunner.class)
@WebAppConfiguration
@AutoConfigureMockMvc
@SpringBootTest(classes = UserAuthApplication.class)
class UserAuthApplicationTests {
@Autowired
private MockMvc mockMvc;
private String obtainAccessToken(final String username, final String password) throws Exception {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "password");
params.add("username", username);
params.add("password", password);
ResultActions result = mockMvc
.perform(post("/userauth/oauth/token").params(params).with(httpBasic("user-test","testp"))
.accept("application/json"))
.andExpect(status().isOk())
.andExpect((ResultMatcher) content());
String resultString = result.andReturn().getResponse().getContentAsString();
JacksonJsonParser jsonParser = new JacksonJsonParser();
return jsonParser.parseMap(resultString).get("access_token").toString();
}
@Test
public void tokenNotGiven_whenGetSecureRequest_thenUnauthorized() throws Exception {
mockMvc.perform(get("/userauth/apis/v1/users").param("email", ""))
.andExpect(status().isUnauthorized());
}
@Test
public void givenValidUserCredentials_whenGetSecureRequest_thenAuthorized() throws Exception {
String accessToken = obtainAccessToken("test@gmail.com", "test1");
mockMvc.perform(get("/userauth/apis/v1/users")
.header("Authorization", "Bearer " + accessToken)
.param("email", ""))
.andExpect(status().isOk());
mockMvc.perform(get("/userauth/apis/v1/users")
.header("Authorization", "Bearer " + accessToken)
.param("email", ""))
.andExpect(status().isOk())
.andExpect((ResultMatcher) content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.success", is(true)));
}
}
当我运行上面的测试用例时,它给予我下面的错误:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /userauth/oauth/token
Parameters = {grant_type=[password], username=[test@gmail.com], password=[test1]}
Headers = [Accept:"application/json", Authorization:"Basic dXNlci1hdXRoOm1hbm9q"]
Body = null
Session Attrs = {}
Handler:
Type = null
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 401
Error message = null
Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Content-Type:"application/json", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
Content type = application/json
Body = {"status":"UNAUTHORIZED","message":"Full authentication is required to access this resource"}
Forwarded URL = null
Redirected URL = null
Cookies = []
预计它应该生成令牌,即使在基于ReactJS的应用程序中也可以生成和正常工作,但它只在jUnit中失败。
2条答案
按热度按时间wko9yo5t1#
MockMvc
的好处是,您可以使用模拟的Servlet环境和案例使用Spring Security Test支持来基本上 * 设置 *SecurityContext
中的用户。如果您 * 只是 * 想测试HTTP端点,这可以让您不必准备任何令牌。确保在项目中具有以下依赖项:
然后你可以在测试方法级别上使用
@WithMockUser(username="mike")
,或者在执行请求时使用MockMvc
:如果您仍然想测试安全流,我建议您在测试中使用
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
,而不要使用MockMvc
。然后,您可以使用自动配置的TestRestTemplate
或WebTestClient
,首先执行令牌检索,然后使用 * 真实的 * Servlet环境访问您的端点。00jrzges2#
我无法得到rieckpil回答为我工作,由于这个变化在这里提到-https://github.com/spring-attic/spring-security-oauth/issues/360
如果HTTP请求不包含令牌标头,但用户已通过身份验证,则安全上下文将被清除。这在过滤器链的下游导致了问题,因为用户被再次检查以查看他们是否被认证,但是在上下文被清除的情况下,他们被认为是匿名用户,因此请求将返回401。
为了解决这个问题,我们可以将无状态布尔值设置为false,这将防止上下文被清除。