package eriji.com.oauth; import oauth.signpost.OAuth; import oauth.signpost.OAuthConsumer; import oauth.signpost.OAuthProvider; import oauth.signpost.basic.DefaultOAuthProvider; import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; import oauth.signpost.exception.OAuthCommunicationException; import oauth.signpost.exception.OAuthExpectationFailedException; import oauth.signpost.exception.OAuthMessageSignerException; import oauth.signpost.exception.OAuthNotAuthorizedException; import oauth.signpost.signature.HmacSha1MessageSigner; import org.apache.http.HttpRequest; import android.util.Log; public class OAuthClient { protected Logger logger = Logger.getLogger(OAuthClient.class); protected OAuthConsumer mConsumer = null; protected OAuthProvider mProvider = null; protected OAuthRequestToken mRequestToken = null; protected OAuthAccessToken mAccessToken = null; private OAuthStore mStore = null; /** * @param consumer_key * @param consumer_secret * @param base_url end with '/' */ public OAuthClient(String consumer_key, String consumer_secret, String base_url, OAuthStore store) { this(consumer_key, consumer_secret, base_url + "/request_token", base_url + "/access_token", base_url + "/authorize", store); } public OAuthClient(String consumer_key, String consumer_secret, String requestTokenEndpointUrl, String accessTokenEndpointUrl, String authorizationWebsiteUrl, OAuthStore store) { mStore = store; Log.i("LDS", consumer_key + " " + consumer_secret); mConsumer = new CommonsHttpOAuthConsumer(consumer_key, consumer_secret); mProvider = new DefaultOAuthProvider(requestTokenEndpointUrl, accessTokenEndpointUrl, authorizationWebsiteUrl); // 饭否API服务器目前只支持HMAC_SHA1签名方式 mConsumer.setMessageSigner(new HmacSha1MessageSigner()); } /** * 向服务器请求一个request token * * @return 返回服务器认证网址 * @throws OAuthMessageSignerException * @throws OAuthNotAuthorizedException * @throws OAuthExpectationFailedException * @throws OAuthCommunicationException * @throws OAuthStoreException */ public String retrieveRequestToken() throws OAuthMessageSignerException, OAuthNotAuthorizedException, OAuthExpectationFailedException, OAuthCommunicationException, OAuthStoreException { logger.debug("retrieve request token, key/secret : " + mConsumer.getConsumerKey() + " " + mConsumer.getConsumerSecret() + " " + mProvider.getRequestTokenEndpointUrl()); String authUrl = mProvider.retrieveRequestToken(mConsumer, OAuth.OUT_OF_BAND); mRequestToken = new OAuthRequestToken(mConsumer.getToken(), mConsumer.getTokenSecret()); storeRequestToken(); logger.info("Please Go to : " + authUrl); return authUrl; } /** * 用户在服务器网站上确认授权给request token后, 服务器返回用户pinCode * 用户输入此pinCode则表示服务器已经认证 * 此时利用已被用户授权的这个request token和服务器交换得到access token * * @param pinCode oauth_verifier * @throws OAuthMessageSignerException * @throws OAuthNotAuthorizedException * @throws OAuthExpectationFailedException * @throws OAuthCommunicationException * @throws OAuthClientException * @throws OAuthStoreException */ public void retrieveAccessToken(String pinCode) throws OAuthMessageSignerException, OAuthNotAuthorizedException, OAuthExpectationFailedException, OAuthCommunicationException, OAuthStoreException, OAuthClientException { OAuthToken token = getRequestToken(); mConsumer.setTokenWithSecret(token.getToken(), token.getTokenSecret()); mProvider.retrieveAccessToken(mConsumer, pinCode); mAccessToken = new OAuthAccessToken(mConsumer.getToken(), mConsumer.getTokenSecret()); storeAccessToken(); logger.info("retrieve access token, request token/token secret." + mConsumer.getToken() + " " + mConsumer.getTokenSecret() + " " + mProvider.getAccessTokenEndpointUrl()); } public OAuthConsumer getConsumer() { return mConsumer; } public OAuthProvider getProvider() { return mProvider; } public void setStore(OAuthStore store) { mStore = store; } /** * 储存request token * * @throws OAuthStoreException */ public void storeRequestToken() throws OAuthStoreException { mStore.store(mConsumer.getConsumerKey(), mRequestToken); } /** * 储存access token * * @throws OAuthStoreException */ public void storeAccessToken() throws OAuthStoreException { mStore.store(mConsumer.getConsumerKey(), mAccessToken); // TODO: delete request token } /** * 取得储存器中的request token * * @return request token or NULL * @throws OAuthStoreException * @throws OAuthClientException * @throws OAuthMessageSignerException * @throws OAuthNotAuthorizedException * @throws OAuthExpectationFailedException * @throws OAuthCommunicationException */ public OAuthToken getRequestToken() throws OAuthStoreException, OAuthClientException, OAuthMessageSignerException, OAuthNotAuthorizedException, OAuthExpectationFailedException, OAuthCommunicationException { String key = mConsumer.getConsumerKey(); if (mRequestToken != null) { return mRequestToken; } else { return mStore.get(key, OAuthToken.REQUEST_TOKEN); } } /** * 取得储存中的access token * * @return access token or NULL * @throws OAuthStoreException * @throws OAuthClientException * @throws OAuthMessageSignerException * @throws OAuthNotAuthorizedException * @throws OAuthExpectationFailedException * @throws OAuthCommunicationException */ public OAuthToken getAccessToken() throws OAuthStoreException, OAuthClientException, OAuthMessageSignerException, OAuthNotAuthorizedException, OAuthExpectationFailedException, OAuthCommunicationException { String key = mConsumer.getConsumerKey(); if (mAccessToken != null) { return mAccessToken; } else { return mStore.get(key, OAuthToken.ACCESSS_TOKEN); } } /** * 给HttpRequest加入OAuth认证信息 * * @param request HTTP请求 * @throws OAuthClientException */ public void signRequest(HttpRequest request) throws OAuthClientException { try { OAuthToken accessToken = getAccessToken(); if (null != accessToken) { logger.debug("Sign request with access token : " + accessToken); // OAuthConsumer consumer = new CommonsHttpOAuthConsumer(mConsumer.getConsumerKey(), // mConsumer.getConsumerSecret()); mConsumer.setTokenWithSecret(accessToken.getToken(), accessToken.getTokenSecret()); mConsumer.sign(request); } else { logger.error("Don't has a access token yet."); String authUrl = retrieveRequestToken(); throw new Exception("Unauthorized, please goto " + authUrl ); } } catch (Exception e) { throw new OAuthClientException("Cann't sign request: " + e.getMessage(), e); } } /** * 快速检查储存器已有access token * * @return */ public boolean hasAccessToken() { return mStore.isExists(mConsumer.getConsumerKey(), OAuthToken.ACCESSS_TOKEN); } }