2011-04-28 2 views
1

J'ai un example web.py app fournissant des services REST + OAuth2. En Python, une application client passe par le processus de génération d'un consommateur OAuth2, demande, signer, etc. quelque chose comme ça (pseudo référence de code, pas terminé):OAuth2 à deux jambes Exemple en Java?

import json 
import time 
import oauth2 
import urllib2 

# Set up the POST variables 
method = 'POST' 
url = 'https://localhost/service/rest' 
parameters = { 
    'username' : username, 
    'password' : password 
} 

# Generate our Consumer object 
consumer = oauth2.Consumer(key = KEY, secret = SECRET) 

# Add additional parameters required by OAuth 
parameters['oauth_version']  = "1.0" 
parameters['oauth_nonce']  = oauth2.generate_nonce() 
parameters['oauth_timestamp'] = int(time.time()) 
parameters['oauth_consumer_key'] = consumer.key 

# Generate and sign the request 
oauth = oauth2.Request(method = method, url = url, parameters = parameters) 
signature_method = oauth2.SignatureMethod_HMAC_SHA1() 
oauth.sign_request(signature_method, consumer, None) 

# Shoot it off to the webserver 
req = urllib2.Request(BASE_URL, oauth.to_postdata()) 
result = urllib2.urlopen(req).read() 
json_result = json.loads(result) 
print json_result 

TADA! Cela fonctionne comme un champion. J'essaie de faire la même chose sous Java, et plus particulièrement sur Android, mais je vais prendre n'importe quoi à ce stade. Tous les exemples que j'ai vus sont axés sur les API OAuth2 publiques utilisant l'authentification à trois pattes ou sont axés sur les configurations côté serveur pour les services Web. Est-ce que quelqu'un peut avoir pitié de moi et me montrer un exemple tout aussi simple en Java en utilisant BasicHttpContext, DefaultHttpClient et les amis?

PLUS TARD ÉDITÉE

Il est probablement considéré comme une mauvaise forme pour répondre à vos propres questions, mais voici comment faire ce que je demandais. Il se trouve que Oauth à deux pattes est vraiment la fonctionnalité OAuth v1.0, donc la bibliothèque oauth.signpost semi-abandonnée peut le faire facilement. J'ai essayé d'utiliser la bibliothèque de joauth plus récemment maintenue, mais je n'ai pas trouvé de bons exemples de la façon de faire juste les bits que je voulais. Ce code est réellement réparti dans trois ou quatre fichiers java différents dans mon code, mais je l'ai fait tous ensemble pour cet exemple de pseudo-code.

import ... 
import oauth.signpost.OAuthConsumer; 
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; 
import oauth.signpost.exception.OAuthCommunicationException; 
import oauth.signpost.exception.OAuthExpectationFailedException; 
import oauth.signpost.exception.OAuthMessageSignerException; 

public class RestClient { 

    private OAuthConsumer oauth_consumer = null; 
    private DefaultHttpClient http_client; 
    private static final String consumer_key = "something"; 
    private static final String consumer_secret = "something_else"; 

    public RestClient(Context context) { 
    // Instantiate our custom http client with our trusted key 
    this.http_client = new DefaultHttpClient(); 
    // Instantiate an oauth_consumer 
    this.oauth_consumer = new CommonsHttpOAuthConsumer(consumer_key, consumer_secret); 
    } 

    public POST(String url, Map params) { 
    // Initialize our post request 
    HttpPost httppost = new HttpPost(url); 
    httppost.setHeader("Accept", "application/json"); 
    httppost.setHeader("Content-type", "application/x-www-form-urlencoded"); 

    // This iterates through the parameters and stores them for use 
    List<NameValuePair> name_value_pairs = new ArrayList<NameValuePair>(2); 
    Iterator iter = params.entrySet().iterator(); 
    while (iter.hasNext()) { 
     Map.Entry pairs = (Map.Entry)iter.next(); 
     name_value_pairs.add(
     new BasicNameValuePair((String)pairs.getKey(), (String)pairs.getValue()) 
    ); 
    } 

    try { 
     // Put our parameters in our Post 
     httppost.setEntity(new UrlEncodedFormEntity(name_value_pairs)); 
     // sign our request 
     this.oauth_consumer.sign(httppost); 
     // Yoiks, and away! 
     HttpResponse response = http_client.execute(httppost); 
     HttpEntity entity = response.getEntity(); 

     if (entity != null) { 
     InputStream instream = entity.getContent(); 
     JSONObject json = new JSONObject(convertStreamToString(instream)); 
     // Closing the input stream will trigger connection release 
     instream.close(); 
     return json; 
     } catch (aBunchOfShit e) { 
     e.printStackTrace(); 
     } 
    } 
    return null; 
    } 
} 

Lorsque vous vérifiez votre signature sur le back-end, assurez-vous d'inclure tous les les paramètres transmis dans la demande. J'ai regardé l'erreur "Signature invalide, chaîne de base attendue POST & ..." pendant une heure jusqu'à ce que je trouve comment régler System.setProperty ("debug", "1"); et vu la chaîne de base d'origine sur le côté Java. Cela fonctionne assez bien pour le moment, mais j'aimerais quand même voir comment cela fonctionne dans une bibliothèque maintenue.

+0

Je ne comprends pas comment vous avez utilisé 'context' comme argument pour' new DefaultHttpClient'. DefaultHttpClient ne prend-il pas un HttpParams? – LuxuryMode

+0

Le code que vous avez utilisé suit l'autorisation OAuth 1.0a mais votre titre demande OAuth à 2 pattes. –

+0

@LuxuryMode qui était juste une faute de frappe. Désolé pour la confusion! – DaGoodBoy

Répondre

1

Depuis que vous avez mentionné à propos de joauth, j'ai écrit un documentation pour autoriser l'autorisation OAuth 1 en utilisant JOAuth.

J'espère que cela vous aide.

Questions connexes