錯誤信息:org.springframework.web.util.NestedServletException: Request processing failed; nested exception is error="invalid_request", error_description="Missing grant type"
錯誤代碼配置:
@Autowired
protected WebApplicationContext wac;
@Autowired
protected FilterChainProxy springSecurityFilterChain;
protected MockMvc mockMvc;
@Before
public void prepare1() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac)
.addFilter(springSecurityFilterChain).build();
}
protected void auth(OAuth2Form oAuth2Form) throws Exception {
OAuth2Token authToken = JsonUtil.readValue(mockMvc.perform(post(SecurityConstants.DEFAULT_OAUTH_TOKEN_URL)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.header("Authorization", AUTHORIZATION)
.content(oAuth2Form.toString()))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString(), new TypeReference<OAuth2Token>() {
});
assertNotNull(authToken);
RegistrationMockJunit.authToken = authToken;
}
錯誤原因:該代碼使用post並且使用json的格式來認證用戶,我的應用代碼中有一個過濾器。它的作用是讀取post的APPLICATION_JSON_UTF8數據轉成APPLICATION_FORM_URLENCODED(oauth2不支持APPLICATION_JSON_UTF8)。當使用junit的時候沒有進入那個過濾器,因爲過濾器是保存在ApplicationFilterChain中的,不是保存在FilterChainProxy,使用junit的時候ApplicationFilterChain將替換成MockFilterChain,所以有以上的錯誤。
解決辦法將代碼採用APPLICATION_FORM_URLENCODED格式提交
protected void auth(OAuth2Form oAuth2Form) throws Exception {
OAuth2Token authToken = JsonUtil.readValue(mockMvc.perform(post(SecurityConstants.DEFAULT_OAUTH_TOKEN_URL)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.header("Authorization", AUTHORIZATION)
.params(oAuth2Form.convert()))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString(), new TypeReference<OAuth2Token>() {
});
assertNotNull(authToken);
RegistrationMockJunit.authToken = authToken;
}
@Getter
public static class OAuth2Form implements Serializable {
@JsonProperty("grant_type")
private String grantType;
private String username;
private String password;
private String scope;
public OAuth2Form(String grantType, String username, String password, String scope) {
this.grantType = grantType;
this.username = username;
this.password = password;
this.scope = scope;
}
public OAuth2Form(String username, String password) {
this.grantType = "password";
this.username = username;
this.password = password;
this.scope = "all";
}
public String toString() {
try {
return JsonUtil.serialize(this);
} catch (IOException e) {
return "";
}
}
public MultiValueMap<String, String> convert(){
MultiValueMap<String, String> result = new LinkedMultiValueMap<>();
result.add("grant_type", this.grantType);
result.add("username", this.username);
result.add("password", this.password);
result.add("scope", this.scope);
return result;
}
}