2012-11-07 5 views
5

Ich verwende Delphi XE2 mit Indy 10, um auf die Ubuntu One API zuzugreifen. So weit, ist es gut. Ich konnte das OAuth-Token aus der Cloud als described abrufen. Jetzt möchte ich mit der API (wie described) starten:Der Zugriff auf Ubuntu One API führt zu "401 UNAUTHORIZED" oder "400 BAD REQUEST"

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; 

Aufruf https://one.ubuntu.com/api/file_storage/v1 Ergebnisse in "401 Unauthorized". Wenn Sie https://one.ubuntu.com/api/account/ aufrufen, wird "400 BAD REQUEST" angezeigt. Die OAuth-Bibliothek ist von SourceForge und arbeitet mit Dropbox (Dropbox akzeptiert die OAuth-Params, wenn sie im Query-String sind). Die Token sind korrekt und gültig. Was mache ich falsch?

BTW:

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; 

Antwort

1

An dieser Stelle die neu erstellt Token auf dem Ubuntu-SSO-Dienst zu anderen Verfahren zur Authentifizierung verwendet werden, können aber noch nicht mit der Ubuntu One verwendet werden API. Wir müssen Ubuntu One mitteilen, das neu erstellte Token aus dem SSO-Dienst zu kopieren. Dies geschieht, indem Sie eine Anforderung an die folgende URL, die mit dem neuen OAuth-Token signiert ist, an die folgende Adresse senden: GET . Von Ubuntu One: Authorization page.

Schande über mich, ich habe vergessen, das zu tun.