Twitter oauth invalid oauth_verifier parameter

I implement oauth Java with the following sequence:

1) Sending POST https://api.twitter.com/oauth/request_token (with callback) The response to Twitter contains oauth_token, oauth_token_secret and oauth_callback_confirmed = true

2) Redirect to https://api.twitter.com/oauth/authenticate? oauth_token = {oauth_token from a previous response from Twitter}

3) A Twitter login form will appear, click the "Login" button.

4) Twitter redirects to {callback_url}? oauth_token = {this token is equal to the token from the response oauth / request_token} & oauth_verifier = {verifier}

5) POST https://api.twitter.com/oauth/access_token with the Oauth header includes oauth_token, the message body contains oauth_verifier = {return verifier}

6) Twitter response = Error processing your OAuth request: Invalid oauth_verifier parameter

What is wrong with oauth_verifier?

Calculate the signature method:

private static String computeSignature(String baseString, String keyString) throws GeneralSecurityException, UnsupportedEncodingException { SecretKey secretKey = null; byte[] keyBytes = keyString.getBytes(); secretKey = new SecretKeySpec(keyBytes, "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(secretKey); byte[] text = baseString.getBytes(); return new String(Base64.encodeBase64(mac.doFinal(text))).trim(); } 

Code for the first request:

 String oauth_signature_method = "HMAC-SHA1"; // generate any fairly random alphanumeric string as the "nonce". String uuid_string = UUID.randomUUID().toString(); uuid_string = uuid_string.replaceAll("-", ""); String oauth_nonce = uuid_string; // get the timestamp Calendar tempcal = Calendar.getInstance(); long ts = tempcal.getTimeInMillis(); String oauth_timestamp = (new Long(ts / 1000)).toString(); String parameter_string = "oauth_callback=" + OauthConstants.TWITTER_OAUTH_CALLBACK + "&oauth_consumer_key=" + OauthConstants.TWITTER_OAUTH_CONSUMER_KEY + "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method=" + oauth_signature_method + "&oauth_timestamp=" + oauth_timestamp + "&oauth_version=1.0"; String signature_base_string = get_or_post + "&" + encode(twitter_endpoint) + "&" + encode(parameter_string); String oauth_signature = ""; try { oauth_signature = computeSignature(signature_base_string, OauthConstants.TWITTER_OAUTH_CONSUMER_SECRET + "&"); } catch (GeneralSecurityException | UnsupportedEncodingException e) { ...} String twitter_endpoint = "https://api.twitter.com/oauth/request_token"; String authorization_header_string = "OAuth oauth_callback=\"" + OauthConstants.TWITTER_OAUTH_CALLBACK + "\",oauth_consumer_key=\"" + OauthConstants.TWITTER_OAUTH_CONSUMER_KEY + "\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"" + oauth_timestamp + "\",oauth_nonce=\"" + oauth_nonce + "\",oauth_version=\"1.0\",oauth_signature=\"" + encode(oauth_signature) + "\""; // Apache httpcore 4.4.1 HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new RequestContent()) .add(new RequestTargetHost()) .add(new RequestConnControl()) .add(new RequestUserAgent("ApacheHttp/1.1")) .add(new RequestExpectContinue(true)).build(); HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); HttpCoreContext context = HttpCoreContext.create(); HttpHost host = new HttpHost(twitter_endpoint_host, 443); DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024); context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, host); try { // initialize the HTTPS connection SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, null, null); SSLSocketFactory ssf = sslcontext.getSocketFactory(); Socket socket = ssf.createSocket(); socket.connect(new InetSocketAddress(host.getHostName(), host.getPort()), 0); conn.bind(socket); BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest("POST", twitter_endpoint_path, HttpVersion.HTTP_1_1); request2.setEntity(new StringEntity("", "UTF-8")); request2.addHeader("Authorization", authorization_header_string); httpexecutor.preProcess(request2, httpproc, context); HttpResponse response2 = httpexecutor.execute(request2, conn, context); httpexecutor.postProcess(response2, httpproc, context); } catch(Exception e) {} ... 

Code for the second request (redirect to https oauth / authenticate)

 public JSONObject getTwitterAuthorizationCodeFromRequestToken(String oauth_token) { ... String twitter_endpoint = "https://api.twitter.com/oauth/authenticate"; ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); try { FacesContext.getCurrentInstance().getExternalContext().redirect(twitter_endpoint + "?oauth_token=" + encode(oauth_token)); } catch (IOException ex) {...} ... } 

Code for the third request (POST oauth / access_token)

  public JSONObject getTwitterAccessTokenFromAuthorizationCode(String verifier_or_pin, String oauth_token) { ... String oauth_signature_method = "HMAC-SHA1"; // generate any fairly random alphanumeric string as the "nonce". Nonce = Number used ONCE. String uuid_string = UUID.randomUUID().toString(); uuid_string = uuid_string.replaceAll("-", ""); String oauth_nonce = uuid_string; Calendar tempcal = Calendar.getInstance(); long ts = tempcal.getTimeInMillis(); String oauth_timestamp = (new Long(ts / 1000)).toString(); // the parameter string must be in alphabetical order String parameter_string = "oauth_consumer_key=" + OauthConstants.TWITTER_OAUTH_CONSUMER_KEY + "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method=" + oauth_signature_method + "&oauth_timestamp=" + oauth_timestamp + "&oauth_token=" + encode(oauth_token) + "&oauth_version=1.0"; String signature_base_string = get_or_post + "&" + encode(twitter_endpoint) + "&" + encode(parameter_string); String oauth_signature = ""; try { oauth_signature = computeSignature(signature_base_string, OauthConstants.TWITTER_OAUTH_CONSUMER_SECRET + "&"); } catch (GeneralSecurityException | UnsupportedEncodingException e) { ... } String authorization_header_string = "OAuth oauth_consumer_key=\"" + OauthConstants.TWITTER_OAUTH_CONSUMER_KEY + "\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"" + oauth_timestamp + "\",oauth_nonce=\"" + oauth_nonce + "\",oauth_version=\"1.0\",oauth_signature=\"" + encode(oauth_signature) + "\",oauth_token=\"" + encode(oauth_token) + "\""; HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new RequestContent()) .add(new RequestTargetHost()) .add(new RequestConnControl()) .add(new RequestUserAgent("ApacheHttp/1.1")) .add(new RequestExpectContinue(true)).build(); HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); HttpCoreContext context = HttpCoreContext.create(); HttpHost host = new HttpHost(twitter_endpoint_host, 443); DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024); context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, host); try { SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, null, null); SSLSocketFactory ssf = sslcontext.getSocketFactory(); Socket socket = ssf.createSocket(); socket.connect(new InetSocketAddress(host.getHostName(), host.getPort()), 0); conn.bind(socket); BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest("POST", twitter_endpoint_path); // Including oauth_verifier value to request body request2.setEntity(new StringEntity("oauth_verifier=" + encode(verifier_or_pin), "UTF-8")); request2.addHeader("Authorization", authorization_header_string); httpexecutor.preProcess(request2, httpproc, context); HttpResponse response2 = httpexecutor.execute(request2, conn, context); ... } 
+5
source share
1 answer

I faced the same situation with our JavaScript code base. After the battle of the day, I found a solution that resolved the error. This is just adding a Content-Type header with the value " application / x-www-form-urlencoded ".

My code was used to work correctly, but it has stopped working in the last couple of months. I assume that Twitter has changed the implementation of OAuth processing recently, which forces us to explicitly add content.

+2
source

All Articles