Hi All,
I've got the working version now. Tips here:
1. baseString: consumber_key,oauth_token double encode, others encode once.
2. signature key, don't encode
3. request url: encode value once, that is name1=encode(value1)&name2=encode(value2)...
4. don't add secret to baseString
5. signature key for request token is consumber_shared_secret +"&"
6. signature key for access token is consermer_shared_key+ "&" + request_oauth_secret
here is my code
package com.mynode.oauth.myspace;
import java.net.URLEncoder;
import java.security.SignatureException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Random;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import com.google.inject.Inject;
import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
public class MySpaceOAuthService{
final private String requestTokenProviderUrl = "http://api.myspace.com/request_token";
final private String authorizeUrl = "http://api.myspace.com/authorize";
final private String accessTokenProvideUrl = "http://api.myspace.com/access_token";
final private String oauth_signature_method = "HMAC-SHA1";
final private String requestMethod = "GET";
final private String oauth_version = "1.0";
private String oauth_consumer_key;
private String shared_secret;
private String callback_url;
private String oauth_timestamp;
private String oauth_nonce;
private static HashMap> mySpaceKeyMap = new HashMap>();
static{
HashMap signParams=new HashMap();
signParams.put("shared_secret","-----your shared_secret----");
signParams.put("callback_url", "--your callback--");
mySpaceKeyMap.put("--your consumer key--",signParams);
}
@Inject
public MySpaceOAuthService(String oauth_consumer_key) {
this.oauth_consumer_key = oauth_consumer_key;
this.shared_secret = mySpaceKeyMap.get(oauth_consumer_key).get("shared_secret");
this.callback_url = mySpaceKeyMap.get(oauth_consumer_key).get("callback_url");
}
public String getRequestTokenURL() throws Exception{
String requestTokenUrl="";
String requestUrl = this.getRequestTokenUrlBaseString();
String oauth_signature = getRequestTokenUrlSignature(requestUrl);
requestTokenUrl = requestTokenProviderUrl + "?" +
"oauth_consumer_key=" + URLEncoder.encode(oauth_consumer_key,"UTF-8") +
"&oauth_nonce=" + URLEncoder.encode(oauth_nonce,"UTF-8") +
"&oauth_signature=" + URLEncoder.encode(oauth_signature,"UTF-8") +
"&oauth_signature_method=" + URLEncoder.encode(oauth_signature_method,"UTF-8")+
"&oauth_timestamp=" + URLEncoder.encode(oauth_timestamp,"UTF-8") +
"&oauth_version=" + URLEncoder.encode(oauth_version,"UTF-8");
System.out.println("Request Token URL");
System.out.println(requestTokenUrl);
return requestTokenUrl;
}
public String getRequestToken() throws Exception{
String responseText = null;
try{
String requestUrl = getRequestTokenURL();
WebConversation conversation = new WebConversation();
WebRequest request = new GetMethodWebRequest(requestUrl);
WebResponse response = conversation.getResponse(request);
response = conversation.getResponse(request);
responseText = response.getText();
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println("Request Token");
System.out.println(responseText);
return responseText;
}
public String getUserAuthorizationTokenURL() throws Exception{
String userAuthorizationTokenURL = this.getRequestToken();
userAuthorizationTokenURL = authorizeUrl + "?"+"oauth_callback="+callback_url+"&"+userAuthorizationTokenURL;
System.out.println("User Authorization URL");
System.out.println(userAuthorizationTokenURL);
return userAuthorizationTokenURL;
}
public String getAccessToken(String authorizedRequestToken,String oauth_token_secret) throws Exception{
String baseString = this.getAccessTokenUrlBaseString(authorizedRequestToken);
String requestSignature = this.getAccessTokenUrlSignature(baseString, oauth_token_secret);
String accessTokenURL = null;
try{
accessTokenURL = accessTokenProvideUrl + "?" +
"oauth_consumer_key=" + URLEncoder.encode(oauth_consumer_key,"UTF-8") +
"&oauth_nonce=" + URLEncoder.encode(oauth_nonce,"UTF-8") +
"&oauth_signature=" + URLEncoder.encode(requestSignature,"UTF-8") +
"&oauth_signature_method=" + URLEncoder.encode(oauth_signature_method,"UTF-8") +
"&oauth_timestamp=" + URLEncoder.encode(oauth_timestamp,"UTF-8") +
"&oauth_token=" + URLEncoder.encode(authorizedRequestToken,"UTF-8") +
"&oauth_version=" + URLEncoder.encode(oauth_version,"UTF-8");
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println("Access Token Request URL");
System.out.println(accessTokenURL);
WebConversation conversation = new WebConversation();
WebRequest request = new GetMethodWebRequest(accessTokenURL);
WebResponse response = conversation.getResponse(request);
response = conversation.getResponse(request);
String responseText = response.getText();
System.out.println("Access Token");
System.out.println(responseText);
return responseText;
}
private String getAccessTokenUrlBaseString(String authorizedRequestToken) throws Exception{
//set oauth_timestamp and oauth_nonce
updateTimestampAndOnoce();
String encode_oauth_consumer_key = URLEncoder.encode(oauth_consumer_key, "UTF-8");
authorizedRequestToken = URLEncoder.encode(authorizedRequestToken, "UTF-8");
String subBaseString =
"oauth_consumer_key=" + encode_oauth_consumer_key +
"&oauth_nonce=" + oauth_nonce +
"&oauth_signature_method=" + oauth_signature_method +
"&oauth_timestamp=" + oauth_timestamp +
"&oauth_token=" + authorizedRequestToken +
"&oauth_version=" + oauth_version;
String baseString =
requestMethod + "&" +
URLEncoder.encode(accessTokenProvideUrl,"UTF-8")+ "&" +
URLEncoder.encode(subBaseString, "UTF-8");
System.out.println("Access Token Url BaseString");
System.out.println(baseString);
return baseString;
}
private String getRequestTokenUrlBaseString() throws Exception{
//set oauth_timestamp and oauth_nonce
updateTimestampAndOnoce();
String encode_oauth_consumer_key = URLEncoder.encode(oauth_consumer_key, "UTF-8");
String subBaseString =
"oauth_consumer_key=" + encode_oauth_consumer_key +
"&oauth_nonce=" + oauth_nonce +
"&oauth_signature_method=" + oauth_signature_method +
"&oauth_timestamp=" + oauth_timestamp +
"&oauth_version=" + oauth_version;
String baseString =
requestMethod + "&" +
URLEncoder.encode(requestTokenProviderUrl,"UTF-8")+ "&" +
URLEncoder.encode(subBaseString, "UTF-8");
System.out.println("Request Token Url BaseString");
System.out.println(baseString);
return baseString;
}
/**
Use this base string and the partner shared secret in the HMAC-SHA1 one
way hashing algorithm, to generate the signature.
NOTE: OAuth does not mandate a specific signature algorithm,
but HMAC-SHA1 must be used for requests to the MySpace REST API.
The key used in the HMAC-SHA1 algorithm is a concatenation of the
partner shared secret and a token secret delimited by an ampersand (&).
The token secret is sometimes supplied in the body of the request for
the Access Token, but if it is not, the value in the key must be an
empty string. In this case the HMAC-SHA1 key will simply be the
partner shared secret followed by a trailing ampersand
* @return
* @throws Exception
*/
private String getRequestTokenUrlSignature(String baseString) throws Exception{
String key = shared_secret+"&";
String oauth_signature = Signature.calculateRFC2104HMAC(baseString, key);
System.out.println("oauth_signature");
System.out.println(oauth_signature);
return oauth_signature;
}
private String getAccessTokenUrlSignature(String baseString,String oauth_token_secret) throws Exception{
String key = shared_secret+"&"+oauth_token_secret;
String oauth_signature = Signature.calculateRFC2104HMAC(baseString, key);
System.out.println("access token url signature");
System.out.println(oauth_signature);
return oauth_signature;
}
private void updateTimestampAndOnoce(){
Calendar cal = Calendar.getInstance();
long ms = cal.getTimeInMillis();
Long timestamp = new Long(ms / 1000);
this.oauth_timestamp = timestamp.toString();
Random r = new Random();
long nonce1 = r.nextLong();
Long nonce = Math.abs(new Long(nonce1));
this.oauth_nonce = nonce.toString();
}
}
class Signature {
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
public static String calculateRFC2104HMAC(String data, String key)
throws java.security.SignatureException {
String result;
try {
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(),
HMAC_SHA1_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);
byte[ rawHmac = mac.doFinal(data.getBytes());
result = new String(Base64.encodeBase64(rawHmac));
} catch (Exception e) {
throw new SignatureException("Failed to generate HMAC : "
+ e.getMessage());
}
return result;
}
}
Cheers,
Sammi