function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
crtest1crtest1 

400 error when request for access token by using refresh_token in Java

Hi,

 

Here is another similar situation, but this time I tried to request for access token with refresh_token in Java. I got error "java.io.IOException: Server returned HTTP response code: 400 for URL: https://login.salesforce.com/services/oauth2/token". It works if I use a self-submitted html form to get access token from Salesforce.

 

Here is the Java codes for the request:

                String tokenUrl = "https://login.salesforce.com/services/oauth2/token";
		HttpURLConnection httpConnection = null;
		DataOutputStream dos = null;
		
		try{
			StringBuilder sb = new StringBuilder("grant_type=refresh_token");
			sb.append("&client_id=").append("3MVG9Km_cBLhsuPy92UAudTyfc9ka4dxuV.OMS5r0vyIS_ThDWpVFBpenmEEUGIHUrBCeHC28ZqbFDWkcCUAd");
			sb.append("&client_secret=").append("7408566340993550860");
			sb.append("&refresh_token=").append("5Aep861eWO5D.7wJBtkhcv3GwrwrKskc75_Jdh9vHLiDWD3xma5eXdnTYq5PANplHLfLtw.ri7UUA==");
			
			// open the connection for mutli-part POST for the first chunk
	                HttpURLConnection httpConnection = (HttpURLConnection) new URL (tokenUrl).openConnection ();
                        httpConnection.setRequestMethod ("POST");
		        httpConnection.setConnectTimeout (300000); //300s = 5mins
		        httpConnection.setReadTimeout (300000); //300s = 5mins
		
		        httpConnection.setDoInput (true);
		        httpConnection.setDoOutput (true);
	                httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
	                httpConnection.setRequestProperty("Accept", "*/*");
	        
	                dos = new DataOutputStream(httpConnection.getOutputStream());
	                dos.writeBytes(sb.toString());
	                dos.flush();
	        
			StringBuffer responseBuffer = StreamUtils.gatherStream(httpConnection.getInputStream());
			System.out.println("SFDC replied access token: " + responseBuffer.toString());
	        
		} catch (Exception e) {
			String msg = "Failed to get access token when executing....";
		} finally {
            if (httpConnection != null) {
                httpConnection.disconnect();
            }

            if (dos != null) {
                // close the stream
                try {
		    dos.close();
		} catch (IOException e) {
		    // NOTHING TO DO
		}
            }
        }

Also i really appreciate it if you can help me this out.

 

Thanks,

Michael

Best Answer chosen by Admin (Salesforce Developers) 
crtest1crtest1

i changed to user DataOutputStream, and removed setRequestProperty calls. It works now.

All Answers

SuperfellSuperfell

You need to urlencode your parameter values. You also shouldn't wrap the outputStream in a dataOutputStream that's a java specific format, just do getOutputStream.write(sb.toString().getBytes("UTF-8"))

crtest1crtest1

I changed to use encode the parameter values, and removed DataOutpuStream. It still doesn't work. Following are the updated codes.

//get access token
		String tokenUrl = "https://login.salesforce.com/services/oauth2/token";
		HttpURLConnection httpConnection = null;
		OutputStream dos = null;
		
		try{
			StringBuilder sb = new StringBuilder("grant_type=refresh_token");
			sb.append("&client_id=").append(URLEncoder.encode("3MVG9Km_cBLhsuPy92UAudTyfc9ka4dxuV.OMS5r0vyIS_ThDWpVFBpenmEEUGIHUrBCeHC28ZqbFDWkcCUAd"));
			sb.append("&client_secret=").append(URLEncoder.encode("7408566340993550860"));
			sb.append("&refresh_token=").append(URLEncoder.encode("5Aep861eWO5D.7wJBtkhcv3GwrwrKskc75_Jdh9vHLiDWD3xma5eXdnTYq5PANplHLfLtw.ri7UUA=="));
			
			// open the connection for mutli-part POST for the first chunk
	        HttpURLConnection httpConnection = (HttpURLConnection) new URL (restUrl).openConnection ();
        httpConnection.setRequestMethod (method);
        httpConnection.setConnectTimeout (300000); //300s = 5mins
        httpConnection.setReadTimeout (300000); //300s = 5mins
       
        httpConnection.setDoInput (true);
        httpConnection.setDoOutput (true); httpConnection.setRequestProperty("Content-Type", "text/html"); httpConnection.setRequestProperty("Accept", "*/*"); dos = httpConnection.getOutputStream(); dos.write(sb.toString().getBytes("UTF-8")); dos.flush(); StringBuffer responseBuffer = StreamUtils.gatherStream(httpConnection.getInputStream()); System.out.println("SFDC replied access token: " + responseBuffer.toString()); } catch (Exception e) { String msg = "Failed to get access token when executing..."; } finally { if (httpConnection != null) { httpConnection.disconnect(); } if (dos != null) { // close the stream try { dos.close(); } catch (IOException e) { // NOTHING TO DO } } }

 

crtest1crtest1

i changed to user DataOutputStream, and removed setRequestProperty calls. It works now.

This was selected as the best answer
MartinBurgenerMartinBurgener

Hi, I am having the same problem. 

 

Here's my code:

 

        String tokenUrl = "https://login.salesforce.com/services/oauth2/token";
        HttpURLConnection httpConnection = null;

        try {
            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"));
            sb.append("&username=").append(URLEncoder.encode("martin@zukbox.com", "UTF-8"));
            sb.append("&password=").append(URLEncoder.encode("passwordshhh", "UTF-8"));

            // open the connection for mutli-part POST for the first chunk
            httpConnection = (HttpURLConnection) new URL(tokenUrl).openConnection();
            httpConnection.setRequestMethod("POST");
//
            httpConnection.setDoInput(true);
            httpConnection.setDoOutput(true);
            httpConnection.setRequestProperty("content-type", "application/x-www-form-urlencoded");

            httpConnection.getOutputStream().write(sb.toString().getBytes("UTF-8"));

            StringBuilder responseBuffer = WebUtils.gatherStream(httpConnection.getInputStream());
            System.out.println("SFDC replied access token: " + responseBuffer.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (httpConnection != null) {
                httpConnection.disconnect();
            }
        }
    

My user and password are my login credentials to sales force, what am I doing wrong?

Any help or guidance is greatly appreciated.

 

Regards,

Martin

 

Edit:

 

More Info:

I've tried making a post through Poster ( an addon for Firefox to make http requests ) and this is the output:

 

<?xml version="1.0" encoding="UTF-8"?><OAuth><error>invalid_grant</error><error_description>authentication failure - Failed: API security token required</error_description></OAuth>

 

SuperfellSuperfell

When you're making a username/password authentication request (whether it be via the password grant in OAUth2 or the login call in the SOAP API), if the request is from outside of the organizations configured trusted network, you'll need to additionaly specify the users API security token. See the online help for Identity confirmation. (instead of password=password you want password=passwordSecurityToken

Stevan BuzejicStevan Buzejic
Hi.
I am getting the same problem.
I tried with changing password with security token but it doesn't work.I also rested my security token and put the new value, but it doesn't works. Do you have any other suggestion? Thanks in advance
alan alanalan alan

Hi 

I am getting code using oauth and then using Code to get accessToken

here is my code 

HttpClient httpclient = new DefaultHttpClient();
             HttpPost httppost = new HttpPost(url);
             httppost.addHeader("Content-Type", "application/x-www-form-urlencoded");
             // Request parameters and other properties.
             List<NameValuePair> params = new ArrayList<NameValuePair>(2);
             params.add(new BasicNameValuePair("code",code));
             params.add(new BasicNameValuePair("grant_type","authorization_code"));
             params.add(new BasicNameValuePair("client_id",clientId));
             params.add(new BasicNameValuePair("client_secret",clientSecret));
             params.add(new BasicNameValuePair("redirect_uri",redirectUri));
             try {
                httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

Getting 400 Bad request.

 

Can any one help me?