2012-11-07 9 views
5

Sto utilizzando Delphi XE2 con Indy 10 per accedere all'API Ubuntu One. Fin qui tutto bene. Sono stato in grado di ottenere il token OAuth dal cloud come described. Ora voglio iniziare a utilizzare l'API (come described):L'accesso a Ubuntu One API comporta "401 UNAUTHORIZED" o "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; 

Calling https://one.ubuntu.com/api/file_storage/v1 risultati in "401 Unauthorized". Chiamando https://one.ubuntu.com/api/account/ risultati in "400 BAD REQUEST". La libreria OAuth è da SourceForge e funziona con Dropbox (Dropbox accetta OAuth-Params se sono nella stringa di query). I token sono corretti e validi. Che cosa sto facendo di sbagliato?

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; 

risposta

1

A questo punto, il token appena creato può essere utilizzato per l'autenticazione altri metodi, sul servizio Ubuntu SSO, ma non si può ancora essere utilizzato con l'Ubuntu One API. Dobbiamo dire a Ubuntu One di copiare il nuovo token creato da dal servizio SSO. Ciò avviene inviando una richiesta GET al seguente URL, firmata con il nuovo token OAuth. dal Ubuntu One: Authorization page.

Peccato per me, ho dimenticato di farlo.