过去一天我一直在努力为我的Android应用程序实现OAuth。问题发生后我遇到了问题。我只想签署一个请求,将其发送到Web服务并获得回复(我相信这是两条腿的方法)。
我已下载路标:
-signpost核-1.2.1.2
-signpost-commonshttp4-1.2.1.2
我已将jar添加到我的库构建路径中。
是否有特定的地方我需要放置这些jar文件才能使它们正常工作?
我遇到最麻烦的部分是生成签名并最终签署请求。 HttpParemeter不断抛出错误。
有没有办法以编程方式生成baseString?
有人可以指导我使用两条腿的Oauth android特定示例吗?
我的代码如下:
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);
}
答案 0 :(得分:1)
我从未使用过路标,所以我无法帮助你。我只能分享一些我曾经做过的oauth舞蹈代码。我使用scribe,它在1.0和2.0 oauth规范中都可以正常工作。我的webservices需要通过webbrowser进行身份验证,使用webview可以正常工作。下面的代码可能不会编译,但它来自一个工作(但仍在开发中)的应用程序。由于我还在学习安卓,所有评论和更正都是受欢迎的。
整个过程从我用于与webservice通信的活动开始,它只包含最初隐藏的webview。 Init方法就是全部开始的地方:
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);
}
}
}
答案 1 :(得分:1)
库需要位于libs文件夹中(带有s!)然后它们会自动添加到项目的构建路径中。