我正在尝试将现有的 OAuth1.0 3L 令牌迁移到 Web 应用程序的 OAuth2.0。我正在按照https://developers.google.com/accounts/docs/OAuth_ref上的说明进行操作, 尽管我尽了最大努力,但我仍然收到以下回复:“授权标头无效。”
为了创建 Authorization 标头,我使用了 Google 的 Java 客户端库 1.0,我在应用程序中使用它来与 google 日历对话。我正在使用访问令牌进行测试。可以正常工作的令牌秘密、消费者密钥和消费者秘密(即我可以使用这些凭据来调用 Google 日历等)。
这是我使用的代码:
OAuthParameters oauthParameters = new OAuthParameters();
oauthParameters.setOAuthConsumerKey("www.mywebsite.com"); // this is the same consumer key used by my app normally, without problem. mywebsite is an example, the real name is different
oauthParameters.setOAuthConsumerSecret("XXXXX");
oauthParameters.setOAuthToken("YYYYY");
oauthParameters.setOAuthTokenSecret("ZZZZZZ");
OAuthHmacSha1Signer signer = new OAuthHmacSha1Signer();
OAuthHelper oauthHelper = new GoogleOAuthHelper(signer);
String requestUrl = "https://accounts.google.com/o/oauth2/token";
String header = oauthHelper.getAuthorizationHeader(requestUrl, "POST", oauthParameters);
String payload = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Amigration%3Aoauth1&client_id="+clientId+"&client_secret="+clientSecret;
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.addHeader("Authorization", header);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
httpPost.setEntity(new ByteArrayEntity(payload.getBytes()));
String response = httpClient.execute(httpPost, new BasicResponseHandler());
这是 HttpClient 生成的线路跟踪:
>> "POST /o/oauth2/token HTTP/1.1[\r][\n]"
>> "Authorization: OAuth realm="", oauth_signature="ixVbjINI6pgPU2RqXGiQRbPGY%3D", oauth_nonce="486642280771700", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="www.mywebsite.com", oauth_token="YYYYY", oauth_timestamp="1395127834"[\r][\n]"
>> "Content-Type: application/x-www-form-urlencoded[\r][\n]"
>> "Content-Length: 193[\r][\n]"
>> "Host: accounts.google.com[\r][\n]"
>> "Connection: Keep-Alive[\r][\n]"
>> "User-Agent: Apache-HttpClient/4.3.2 (java 1.5)[\r][\n]"
>> "[\r][\n]"
>> "grant_type=urn%ietf%params%oauth%grant-type%migration%oauth1&client_id=12345&client_secret=ABCDE"
<< "HTTP/1.1 400 Bad Request[\r][\n]"
<< "Cache-Control: no-cache, no-store, max-age=0, must-revalidate[\r][\n]"
<< "Pragma: no-cache[\r][\n]"
<< "Expires: Fri, 01 Jan 1990 00:00:00 GMT[\r][\n]"
<< "Date: Tue, 18 Mar 2014 07:30:39 GMT[\r][\n]"
<< "Content-Type: application/json[\r][\n]"
<< "X-Content-Type-Options: nosniff[\r][\n]"
<< "X-Frame-Options: SAMEORIGIN[\r][\n]"
<< "X-XSS-Protection: 1; mode=block[\r][\n]"
<< "Server: GSE[\r][\n]"
<< "Alternate-Protocol: 443:quic[\r][\n]"
<< "Transfer-Encoding: chunked[\r][\n]"
<< "[\r][\n]"
<< "5a[\r][\n]"
<< "{[\n]"
<< " "error" : "invalid_request",[\n]"
<< " "error_description" : "Invalid authorization header."[\n]"
<< "}"
<< "[\r][\n]"
<< "0[\r][\n]"
<< "[\r][\n]"
其中 12345 和 ABCDE 显然是真正的 OAuth2 应用程序凭据的占位符。
我已经两次和三次检查 OAuthParameters 中设置的所有参数是否与当前使用 OAuth1 工作的普通代码相同(即使使用分步调试器来验证 OAuthHmacSha1Signer 计算签名时的值.getSignature())。
我查看了当前使用 OAuth1 的 Google 客户端 API 发送的 HTTP 请求中的 Authorization 标头(并且工作正常),显然除了签名、随机数和时间戳之外,它们看起来与此迁移调用发送的相同。
我什至尝试了一个测试迁移请求,但失败了,然后使用调试器运行旧代码并注入迁移调用使用的方法、URL、nonce 和时间戳,并且旧代码计算的签名是相同的,给定相同的参数。
为什么 Authorization 标头仍被报告为无效的任何线索?