访问Ubuntu One API导致“401 UNAUTHORIZED”或“400 BAD REQUEST”

时间:2012-11-07 10:20:51

标签: delphi oauth indy10

我正在使用带有Indy 10的Delphi XE2来访问Ubuntu One API。到现在为止还挺好。我能够以described的形式从云中获取OAuth令牌。现在我想开始使用API​​(如described):

function TUbuntuOneApi.DoRequest(const URL: String): String;
var
  RequestParams: TStringList;
  HeaderIndex: Integer;
const
  OAuthAuthorisationHeader = 'OAuth realm="", oauth_version="%s", oauth_nonce="%s", oauth_timestamp="%s", oauth_consumer_key="%s", oauth_token="%s", oauth_signature_method="%s", oauth_signature="%s"';

begin
  RequestParams := SignOAuthRequestParams(URL, fOAuthAppToken, fOAuthAccessToken);

{  OAuth realm="", oauth_version="1.0",
  oauth_nonce="$nonce", oauth_timestamp="$timestamp",
  oauth_consumer_key="$consumer_key", oauth_token="$token",
  oauth_signature_method="PLAINTEXT",
  oauth_signature="$consumer_secret%26$token_secret"
  }

  HeaderIndex := IdHTTP.Request.CustomHeaders.IndexOfName('Authorization');
  if HeaderIndex >= 0 then
  begin
    IdHTTP.Request.CustomHeaders.Delete(HeaderIndex);
  end;

  // Solving: http://stackoverflow.com/questions/7323036/twitter-could-not-authenticate-with-oauth-401-error
  IdHTTP.Request.CustomHeaders.FoldLines := false;

  IdHTTP.Request.CustomHeaders.AddValue('Authorization', Format(OAuthAuthorisationHeader, [
      TIdURI.URLDecode(RequestParams.Values['oauth_version']),
      TIdURI.URLDecode(RequestParams.Values['oauth_nonce']),
      TIdURI.URLDecode(RequestParams.Values['oauth_timestamp']),
      TIdURI.URLDecode(RequestParams.Values['oauth_consumer_key']),
      TIdURI.URLDecode(RequestParams.Values['oauth_token']),
      TIdURI.URLDecode(RequestParams.Values['oauth_signature_method']),
      TIdURI.URLDecode(RequestParams.Values['oauth_signature'])
    ]));

  // Execute
  Result := IdHTTP.Get(URL);
  RequestParams.Free;
end;

function TUbuntuOneApi.Test: String;
begin
  //Result := DoRequest('https://one.ubuntu.com/api/file_storage/v1');
  Result := DoRequest('https://one.ubuntu.com/api/account/');
end;

调用https://one.ubuntu.com/api/file_storage/v1会导致“401 UNAUTHORIZED”。调用https://one.ubuntu.com/api/account/会导致“400 BAD REQUEST”。 OAuth库来自SourceForge,可与Dropbox配合使用(Dropbox接受OAuth-Params,如果它们位于Query-String中)。令牌是正确有效的。我做错了什么?

顺便说一句:

function SignOAuthRequestParams(const URL: String; OAuthAppToken, OAuthAccessToken: TOAuthToken): TStringList;
var
  Consumer: TOAuthConsumer;
  ARequest: TOAuthRequest;
  Response: String;
  HMAC: TOAuthSignatureMethod;
begin
  HMAC := TOAuthSignatureMethod_PLAINTEXT.Create;
  // Consumer erzeugen
  Consumer := TOAuthConsumer.Create(OAuthAppToken.Key, OAuthAppToken.Secret);

  // Request erzeugen
  ARequest := TOAuthRequest.Create(URL);
  ARequest := ARequest.FromConsumerAndToken(Consumer, OAuthAccessToken, URL);
  ARequest.Sign_Request(HMAC, Consumer, OAuthAccessToken);

  Result := TStringList.Create;
  Result.AddStrings(ARequest.Parameters);

  ARequest.Free;
  Consumer.Free;
  HMAC.Free;
end;

1 个答案:

答案 0 :(得分:1)

  

此时,新创建的令牌可用于进行身份验证   其他方法,在Ubuntu SSO服务上,但还不能用   Ubuntu One API。我们需要告诉Ubuntu One新复制   从SSO服务创建令牌。这是通过发出GET来完成的   请求使用新OAuth令牌签名的以下网址。   来自Ubuntu One: Authorization page

对我感到羞耻,我忘了这样做。