Question

I've been struggling of the past day to get OAuth implemented for my android app. I've ran into problem after problem. I just want to sign a request , send it to a web service and get a response back (I believe this is the two legged approach).

I've download signpost:

-signpost-core-1.2.1.2

-signpost-commonshttp4-1.2.1.2

I've added the jars to my library build path.

Is there somewhere specific I need to place these jar files in order for them to work?

The part that I've been having the most trouble with is generating a signature and finally signing the request. Errors keep getting thrown for the HttpParemeters.

Is there a way for me to programatically generate a baseString ?

Can someone direct me to a two legged Oauth android specific example that works ?

My Code below:

public void excecuteSigning(String targetURL){
        String SOAP_ACTION = "http://amebatv.com/api/authDevice";
        System.setProperty("http.keepAlive", "false");      
        HttpURLConnection _request = null;  
        DefaultHttpClient httpclient = null;

    try{ 

        CONSUMER_SECRET  = app_pref.getString("consumerSecret", "");
        CONSUMER_KEY = app_pref.getString("consumerKey", "");   
        String oaut_token = app_pref.getString("accessToken", "");
        String tokenSecret = app_pref.getString("tokenSecret", "");
        String deviceId = deviceInfo.getSerial();


        CommonsHttpOAuthConsumer  consumer = new CommonsHttpOAuthConsumer (CONSUMER_KEY,CONSUMER_SECRET);
        consumer.setTokenWithSecret(oaut_token, tokenSecret); 

        //HttpRequest request;
        HttpParameters requestParameters = new HttpParameters();
        requestParameters.put("file", "vacation.jpg");
        requestParameters.put(OAuth.OAUTH_CONSUMER_KEY, "dpf43f3p2l4k3l03");
        requestParameters.put(OAuth.OAUTH_NONCE, "kllo9940pd9333jh");
        requestParameters.put(OAuth.OAUTH_SIGNATURE_METHOD, "HMAC-SHA1");
        requestParameters.put(OAuth.OAUTH_TIMESTAMP, "1191242096");
        requestParameters.put(OAuth.OAUTH_TOKEN, "nnch734d00sl2jdk");
        requestParameters.put(OAuth.OAUTH_VERSION, "1.0");
        requestParameters.put("size", "original");


        HttpPost request = new HttpPost(targetURL);
        SignatureBaseString baseString = new SignatureBaseString((HttpRequest) request, requestParameters);

        String base = baseString.generate();
        System.out.println(":"+base);

        System.out.println(computeHmac(base,"kd94hf93k423kf44&pfkkdhi9sl3r4s00"));

       httpclient = new DefaultHttpClient();

        ContentProducer cp = new ContentProducer() {
            public void writeTo(OutputStream outstream) throws IOException {
                Writer writer = new OutputStreamWriter(outstream, "UTF-8");
                writeXml(writer);
            }
        };

       HttpParameters params = new HttpParameters();
       HttpEntity entity = new EntityTemplate(cp);
       HttpPost request = new HttpPost(targetURL);         

       request.addHeader("Authorization",AUTH_HEADER);
       request.addHeader("Content-Type", "text/xml; charset=utf-8");
       //request.addHeader("Content-Length",""+soapXML.getBytes().length);
       request.addHeader("SOAPAction",SOAP_ACTION);
       request.setEntity(entity);

        // sign the request
        consumer.sign(request);
        // send the request
        //request.connect();
        HttpResponse response = httpclient.execute(request);

        //get response               
        //StringBuffer response = new StringBuffer();
        InputStream instream = null;    
        BufferedReader br = null;        
         try{            
             int respcode = response.getStatusLine().getStatusCode();
             Log.i("Server Response", ""+respcode);

             //get XML from InputStream
            if(respcode>= 200){ 
                instream =  response.getEntity().getContent();                  
                client.buildDoc(instream);      
            }
            else{
                Log.i("Server Response", ""+respcode);
                //instream = request.getErrorStream();
                }

        }catch(Exception e){
            Log.i("SPLASH","Unable to create connection stream");
            e.printStackTrace();
        }
         finally {      
          if(instream != null) {
            Log.i("SPLASH","Disconnecting stream");
            instream.close();
          }
         }
             */
    }
    catch(Exception e){
        Log.i("SPLASH","Unable to create connection");
        e.printStackTrace();
    }finally {      
          if(httpclient != null) {
            Log.i("SPLASH","Disconnecting");
            httpclient.getConnectionManager().shutdown();
          }
    }
}

/*
 * Method:computeHmac()
 * @params: String, String
 * return: String 
 */
public String computeHmac(String baseString, String key)
                                throws NoSuchAlgorithmException, 
                                InvalidKeyException, 
                                IllegalStateException, 
                                UnsupportedEncodingException
    {

        Mac mac = Mac.getInstance("HmacSHA1");
        SecretKeySpec secret = new SecretKeySpec(key.getBytes(), mac.getAlgorithm());
        mac.init(secret);
        byte[] digest = mac.doFinal(baseString.getBytes());
        return Base64.encodeToString(digest,Base64.URL_SAFE);
    }
Was it helpful?

Solution

Libraries need to be in the libs folder (with an s!) Then they are automatically added to the build path of your project.

OTHER TIPS

I have never used signpost so I cant help you with that. I can only share some code I have worked on to do oauth dance. I use scribe, and it works fine both with 1.0 and 2.0 oauth specs. My webservices require authentication over webbrowser which works fine using webview. Below code probably wont compile but it comes from a working (but still under development) application. Since I am still learning android all comments and corrections are welcome.

Whole process is started from activity that I use for communicating with webservice, it contains inside only webview which is initially hidden. Init method is where all starts:

    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;

    import org.scribe.builder.ServiceBuilder;
    import org.scribe.builder.api.DefaultApi10a;
    import org.scribe.model.OAuthRequest;
    import org.scribe.model.Response;
    import org.scribe.model.Token;
    import org.scribe.model.Verb;
    import org.scribe.model.Verifier;
    import org.scribe.oauth.OAuthService;

    import android.app.Activity;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;

    public class FCEHttpHelper {
        public static final String LOG_TAG = FCEHttpHelper.class.getSimpleName(); 

      //api_key/oauth_key
      //string that is given to you by webservice provider to uniquely identify your app
        final static String APIKEY = "xxxxxx"; 

      //oauth_secret
      //also given to you by service provider
        final static String APISECRET = "yyyyyyy";

      //callback sent to webview after authorization
      //some services allow you to set it up manually, ie. Quizlet
        final static String CALLBACK = "oauth://flashcardexchange";

      //scribe classes
        Token token;
        OAuthService serviceBuilder;

        static class GetUrl extends AsyncTask<String, Integer, String> {
            public Token t;
            public OAuthService serviceBuilder;
            public Activity act;
            public Handler handler;

            protected String doInBackground(String... urls) {           
                String resp = "";

                if (t != null) {
                    OAuthRequest req = new OAuthRequest(Verb.GET, urls[0]);
                    serviceBuilder.signRequest(t, req);
                    Response response = req.send();
                    resp = response.getBody();
                }
                else {
                    URL url = null;
                    try {
                        url = new URL(urls[0]);
                    } catch (MalformedURLException e) {
                        Log.d(LOG_TAG, e.getMessage());
                    }

                    HttpURLConnection urlConnect = null;
                    try {
                        urlConnect = (HttpURLConnection) url.openConnection();
                        resp = StringUtils.convertStreamToString(urlConnect
                                .getInputStream());

                    } catch (Exception e) {
                        Log.d("RESP", "URL ex", e);
                    } finally {
                        if (urlConnect != null)
                            urlConnect.disconnect();
                    }
                }
                return resp;
            }

            protected void onProgressUpdate(Integer... progress) {
            }

            protected void onPostExecute(String result) {
                //Log.i(LOG_TAG, result);
                Intent data = new Intent();
                Bundle extras = new Bundle();
                extras.putString("RESULT", result);
                data.putExtras(extras);
                act.setResult(Activity.RESULT_OK, data);
                act.finish();
            }
        }

        @Override
        public void Destroy() {
        }

        @Override
        public void Init(final Activity act, final WebView webView, boolean oauthRequired, final Handler handler) {
            Intent intent = act.getIntent();
            final String surl = intent.getStringExtra(INTENT_URL);

            if ( !oauthRequired ) {
                GetUrl gurl = new GetUrl();
                gurl.t = null;
                gurl.serviceBuilder = null;
                gurl.act = act;
                gurl.handler = handler;
                gurl.execute(surl);         
                return;
            }

            // get saved token from database, if it does not exists then web authentication is required

            // set up service and get request token as seen on scribe website
            // https://github.com/fernandezpablo85/scribe-java/wiki/Getting-Started
            serviceBuilder = new ServiceBuilder()
                    .provider(new DefaultApi10a() {

              /// example is for flashcardexchange oauth

                        @Override
                        public String getRequestTokenEndpoint() {
                            return "https://secure.flashcardexchange.com/oauth_request_token";
                        }

                        @Override
                        public String getAccessTokenEndpoint() {
                            return "https://secure.flashcardexchange.com/oauth_access_token";
                        }

                        @Override
                        public String getAuthorizationUrl(
                                org.scribe.model.Token requestToken) {
                            return "https://secure.flashcardexchange.com/oauth_login"
                                    + "?oauth_token=" + requestToken.getToken();
                        }
                    }).apiKey(APIKEY).apiSecret(APISECRET).callback(CALLBACK)
                    .debug()
                    .build();

            if (token == null) {

                Message msg = new Message();
                msg.what=1;
                handler.sendMessage(msg);

                webView.setVisibility(View.VISIBLE);

                final Token requestToken = serviceBuilder.getRequestToken();
                final String authURL = serviceBuilder
                        .getAuthorizationUrl(requestToken);

                // attach WebViewClient to intercept the callback url
                webView.setWebViewClient(new WebViewClient() {

                    @Override
                    public boolean shouldOverrideUrlLoading(WebView view, String url) {

                        // check for our custom callback protocol
                        // otherwise use default behavior
                        if (url.startsWith("oauth")) {
                            // authorization complete hide webview for now.
                            webView.setVisibility(View.GONE);

                            Uri uri = Uri.parse(url);
                            String verifier = uri
                                    .getQueryParameter("oauth_verifier");
                            Verifier v = new Verifier(verifier);

                            // save this token for practical use.
                            Token accessToken = serviceBuilder.getAccessToken(
                                    requestToken, v);

                            // host oauth detected from callback
                            // oauth://flashcardexchange
                            if (uri.getHost().equals("flashcardexchange")) {

                                // save accessToken to database to use it later

                                webView.setVisibility(View.GONE);

                                Message msg = new Message();
                                msg.what=2;
                                handler.sendMessage(msg);

                                GetUrl gurl = new GetUrl();
                                gurl.t = accessToken;
                                gurl.act = act;
                                gurl.handler = handler;
                                gurl.serviceBuilder = serviceBuilder;
                                gurl.execute(surl);                         
                            }

                            return true;
                        }

                        return super.shouldOverrideUrlLoading(view, url);
                    }
                });

                // send user to authentication page
                webView.loadUrl(authURL);
            } else {
                webView.setVisibility(View.GONE);

                GetUrl gurl = new GetUrl();
                gurl.t = token;
                gurl.serviceBuilder = serviceBuilder;
                gurl.act = act;
                gurl.handler = handler;
                gurl.execute(surl);
            }       
        }   
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top