简体   繁体   中英

{"error":"unsupported_grant_type","error_description":"grant type not supported"} SalesForce Java

having trouble figuring out what im doing wrong here. attempting to get an access token via SF's API in a selenium test (java), and keep getting the same error. made the exact same call in cypress (javascript) and it worked perfectly fine, however, i can't go that route for other reasons (SF hates UI tests). i think it might have something to do with the fact that it has to be form data, and java is just being weird about it? idk, pls help, im scared.

already tried setting the request body as one long string instead of adding everything into a JSONObject , but that still didn't work

        URL obj = new URL("https://login.salesforce.com/services/oauth2/token");
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
        con.setDoOutput(true);
        con.setDoInput(true);
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        JSONObject body = new JSONObject();
        body.put("grant_type", "password");
        body.put("client_id", "***");
        body.put("client_secret", "***");
        body.put("username", "tyler+prod@pactsafe.com");
        body.put("password", "***");
//        String jsonInputString = "{ grant_type: 'password', client_id: '***', client_secret: '***', password: '***', username: 'tyler+prod@pactsafe.com'";

        System.out.println(body.toString());

        OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
        wr.write(body.toString());
        wr.flush();

        int httpResult = con.getResponseCode();
        InputStream inputStream;
        if (200 <= httpResult && httpResult <= 299) {
            inputStream = con.getInputStream();
        } else {
            inputStream = con.getErrorStream();
        }

        BufferedReader in = new BufferedReader(
                new InputStreamReader(inputStream));

        StringBuilder response = new StringBuilder();
        String currentLine;

        while ((currentLine = in.readLine()) != null)
            response.append(currentLine);

        in.close();


        System.out.println(response.toString());
        System.out.println(httpResult);

        driver.get("https://na85.lightning.force.com/lightning/setup/SetupOneHome/home");

and i get this:

{"password":"***","grant_type":"password","client_secret":"***","client_id":"***","username":"tyler+prod@pactsafe.com"}
{"error":"unsupported_grant_type","error_description":"grant type not supported"}
400

was not encoding my form values properly. fixed by doing something similar to this:

StringBuilder sb = new StringBuilder("grant_type=password");
sb.append("&client_id=").append(URLEncoder.encode("client_id__shhhh, "UTF-8"));
sb.append("&client_secret=").append(URLEncoder.encode("secret shhhhh", "UTF-8"));

The below answer is very misleading and have no idea what Tyler fixed, he should have had the courtesy to post his working code.

I ended up breaking my head for a while as I use a RestTemplate and most of the answers using a MultiValueMap<String, Object> for x-www-form-urlencoded body will give you this error in Salesforce {“error”:“unsupported_grant_type”,“error_description”:“grant type not supported”}.

I finally found the solution by trial and error. The below code works like a charm !

I am using a Rest Template to achieve this:

public String getAccessTokenBody() throws Exception {
    
    try
    {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/x-www-form-urlencoded");
        
        UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance().host("YOUR-INSTANCE.my.salesforce.com").scheme("https").pathSegment("services/oauth2/token")
                .queryParam("grant_type", "password")
                .queryParam("client_id", "your client id")
                .queryParam("client_secret", "your client secret")
                .queryParam("username", "your user name")
                .queryParam("password", "your password");
        HttpEntity requestEntity = new HttpEntity<>(headers);
        ResponseEntity<String> response = restTemplate.postForEntity(uriComponentsBuilder.build().toString().trim(), requestEntity, String.class);
        return response.getBody();
        
    }catch (HttpClientErrorException httpClientErrorException){
        ResponseEntity<String> responseEntity = new ResponseEntity<>(httpClientErrorException.getResponseBodyAsString(), httpClientErrorException.getStatusCode());
        throw new Exception(responseEntity.getBody());
    }
    catch (HttpStatusCodeException httpStatusCodeException) {
        ResponseEntity<String> responseEntity = new ResponseEntity<>(httpStatusCodeException.getResponseBodyAsString(), httpStatusCodeException.getStatusCode());
        throw new Exception(responseEntity.getBody());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM