Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rest Api call gives error 400 using Spring Oauth2

I'm building a rest API using Spring security Oauth2 to secure it.

The following curl command runs succesfully and I get the token:

curl -X POST -vu clientapp:123456 http://localhost:8080/dms-application-0.0.1-SNAPSHOT/oauth/token -H "Accept: application/json" -d "password=spring&username=roy&grant_type=password&scope=read%20write&client_secret=123456&client_id=clientapp"

The following test to get the token also runs succesfully:

@Test
public void getAccessToken() throws Exception {
    String authorization = "Basic " + new String(Base64Utils.encode("clientapp:123456".getBytes()));
    String contentType = MediaType.APPLICATION_JSON + ";charset=UTF-8";

    // @formatter:off
    String content = mvc
            .perform(
                    post("/oauth/token")
                            .header("Authorization", authorization)
                            .contentType(
                                    MediaType.APPLICATION_FORM_URLENCODED)
                            .param("username", "roy")
                            .param("password", "spring")
                            .param("grant_type", "password")
                            .param("scope", "read write")
                            .param("client_id", "clientapp")
                            .param("client_secret", "123456"))
            .andExpect(status().isOk())
            .andExpect(content().contentType(contentType))
            .andExpect(jsonPath("$.access_token", is(notNullValue())))
            .andExpect(jsonPath("$.token_type", is(equalTo("bearer"))))
            .andExpect(jsonPath("$.refresh_token", is(notNullValue())))
            .andExpect(jsonPath("$.expires_in", is(greaterThan(4000))))
            .andExpect(jsonPath("$.scope", is(equalTo("read write"))))
            .andReturn().getResponse().getContentAsString();

    // @formatter:on

    String token= content.substring(17, 53);
}

However, when calling the rest end point externally from a webapp using Spring RestTemplate gives me a http error 400. Below the code:

@RequestMapping(value = "/authentication", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity authenticate(@RequestBody CredentialsDto credentials) {
    try {

        String email = credentials.getEmail();
        String password = credentials.getPassword();
        String tokenUrl = "http://" + env.getProperty("server.host") + ":8080" + "/dms-application-0.0.1-SNAPSHOT" + "/oauth/token";

        // create request body
        JSONObject request = new JSONObject();
        request.put("username", "roy");
        request.put("password", "spring");
        request.put("grant_type","password");
        request.put("scope","read write");
        request.put("client_secret","123456");
        request.put("client_id","clientapp");


        // set headers
        HttpHeaders headers = new HttpHeaders();

        String authorization = "Basic " + new String(Base64Utils.encode("clientapp:123456".getBytes()));
        String contentType = MediaType.APPLICATION_FORM_URLENCODED.toString();
        headers.set("Authorization",authorization);
        headers.set("Accept","application/json");
        headers.set("Content-Type",contentType);

        HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);

        // send request and parse result
        ResponseEntity<String> loginResponse = restClient.exchange(tokenUrl, HttpMethod.POST, entity, String.class);
       // restClient.postForEntity(tokenUrl,entity,String.class,)
        if (loginResponse.getStatusCode() == HttpStatus.OK) {
            //JSONObject userJson = new JSONObject(loginResponse.getBody());
            String response = loginResponse.getBody();
            return ResponseEntity.ok(response);
        } else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
            // nono... bad credentials
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();

        }

    } catch (Exception e) {
        e.printStackTrace();
        return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
    }
    return null;
}

And the error I get:

"Missing grant type"

Any ideas of what can be wrong or any other ways to do it? Because I'm completely stuck on this.

Thank you

like image 665
fgonzalez Avatar asked Apr 14 '26 08:04

fgonzalez


1 Answers

Try to do it like this:

MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("username", "roy");
map.add("password", "spring");
map.add("grant_type", "password");
map.add("scope", "read write");
map.add("client_secret","123456");
map.add("client_id","clientapp");           

HttpEntity request = new HttpEntity(map, headers);

One more thing, when you ask for a token make sure not to send a json request, but with this header:

headers.add("Content-Type", "application/x-www-form-urlencoded"); 
like image 53
Moshe Arad Avatar answered Apr 16 '26 21:04

Moshe Arad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!