Facebook: receiving an incorrect signature (104) when receiving a session key

I am trying to use the HttpClient library (to call the Facebook REST API endpoints) to get the session key and validate the user ...

My code is here:

RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath*:**/*applicationContext-test.xml" }) public class FacebookUserTest { final String API_KEY = "9e2568d68f182a2957878f3acedd9453"; final String SECRET = "f1298956895d39110be92a672e0d2284"; final String TOKEN = "aa0c41aa4532053e8d0097844ab9bc7d"; final String LOGIN = "http://www.facebook.com/login.php"; final String HOST = "http://www.facebook.com/restserver.php"; private static Logger log = LoggerFactory.getLogger(FacebookUserTest.class); protected FacebookUser FacebookUser; @Test public void testFindUserBySessionKey() throws Exception { loginToFacebook(); String sessionKey = getSessionKey(); } public void loginToFacebook() throws Exception { HttpClient client = new HttpClient(); client.setParams(new HttpClientParams()); client.setState(new HttpState()); GetMethod get = new GetMethod(LOGIN + "?api_key=" + API_KEY + "&v=1.0&auth_token=" + TOKEN); // Get login screen client.executeMethod(get); // Post credentials to login PostMethod post = new PostMethod(LOGIN); post.addParameter(new NameValuePair("api_key", API_KEY)); post.addParameter(new NameValuePair("v", "1.0")); post.addParameter(new NameValuePair("auth_token", TOKEN)); post.addParameter(new NameValuePair("email", " user@email.com ")); post.addParameter(new NameValuePair("pass", "password")); client.executeMethod(post); } public String getSessionKey() throws Exception { HttpClient client = new HttpClient(); // Obtain session key String host = "http://www.facebook.com/restserver.php"; String sessSecret = "false"; String toMd = "api_key=" + API_KEY + "auth_token=" + TOKEN + "format=xmlgenerate_session_secret=" + sessSecret + "method=facebook.auth.getSessionv=1.0" + SECRET; String md5 = Md5Utils.MD5(toMd); PostMethod post = new PostMethod(HOST); NameValuePair[] data = { new NameValuePair("api_key", API_KEY), new NameValuePair("auth_token", TOKEN), new NameValuePair("format", "xml"), new NameValuePair("generate_session_secret", SECRET), new NameValuePair("method", "auth.getSession"), new NameValuePair("sig", md5), new NameValuePair("v", "1.0") }; post.setRequestBody(data); post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); post.setRequestHeader("User-Agent", "Facebook API PHP5 Client 1.1 (curl) 5"); // execute method and handle any error responses. client.executeMethod(post); StringBuilder sb = new StringBuilder(); byte[] b = new byte[4096]; for (int n; (n = post.getResponseBodyAsStream().read(b)) != -1;) { sb.append(new String(b, 0, n)); } String sessionId = sb.toString(); log.warn("Session Id: " + sessionId); return sessionId; } } 

When I run my JUnit test, this is what prints from the console:

 WARN : com.myapp.FacebookUserTest - Session Id: <?xml version="1.0" encoding="UTF-8"?> <error_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd"> <error_code>104</error_code> <error_msg>Incorrect signature</error_msg> <request_args list="true"> <arg> <key>api_key</key> <value>9e2568d68f182a2957878f3acedd9453</value> </arg> <arg> <key>auth_token</key> <value>aa0c41aa4532053e8d0097844ab9bc7d</value> </arg> <arg> <key>format</key> <value>xml</value> </arg> <arg> <key>generate_session_secret</key> <value>f1298956895d39110be92a672e0d2284</value> </arg> <arg> <key>method</key> <value>auth.getSession</value> </arg> <arg> <key>sig</key> <value>fcf80d658f35d66396ac521da7102782</value> </arg> <arg> <key>v</key> <value>1.0</value> </arg> </request_args> </error_response> 

This could be my MD5Utils code:

  public class Md5Utils { private static String convertToHex(byte[] data) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < data.length; i++) { int halfbyte = (data[i] >>> 4) & 0x0F; int two_halfs = 0; do { if ((0 <= halfbyte) && (halfbyte <= 9)) buf.append((char) ('0' + halfbyte)); else buf.append((char) ('a' + (halfbyte - 10))); halfbyte = data[i] & 0x0F; } while (two_halfs++ < 1); } return buf.toString(); } public static String MD5(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md; md = MessageDigest.getInstance("MD5"); byte[] md5hash = new byte[32]; md.update(text.getBytes("iso-8859-1"), 0, text.length()); md5hash = md.digest(); return convertToHex(md5hash); } } 

What can I do wrong to create the wrong signature?

I would really appreciate it if someone could help me or point me in the right direction ...

Happy programming and thanks for reading!

+1
java rest junit facebook
source share
2 answers

try it

  string GenerateSignature(IDictionary<string, string> parameters) { StringBuilder signatureBuilder = new StringBuilder(); // Sort the keys of the method call in alphabetical order List<string> keyList = ParameterDictionaryToList(parameters); keyList.Sort(); // Append all the parameters to the signature input paramaters foreach (string key in keyList) signatureBuilder.Append(String.Format(CultureInfo.InvariantCulture, "{0}={1}", key, parameters[key])); // Append the secret to the signature builder signatureBuilder.Append(ConfigurationManager.AppSettings["FBApiSecret"]); MD5 md5 = MD5.Create(); // Compute the MD5 hash of the signature builder byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(signatureBuilder.ToString().Trim())); // Reinitialize the signature builder to store the actual signature signatureBuilder = new StringBuilder(); // Append the hash to the signature foreach (byte hashByte in hash) signatureBuilder.Append(hashByte.ToString("x2", CultureInfo.InvariantCulture)); return signatureBuilder.ToString(); } string CreateHTTPParameterList(IDictionary<string, string> parameterList) { StringBuilder queryBuilder = new StringBuilder(); parameterList.Add("api_key", ConfigurationManager.AppSettings["FBApiKey"]); parameterList.Add("v", "1.0"); parameterList.Add("call_id", DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture)); parameterList.Add("sig", GenerateSignature(parameterList)); //parameterList.Add("sig", _sig); // Build the query foreach (KeyValuePair<string, string> kvp in parameterList) { queryBuilder.Append(kvp.Key); queryBuilder.Append("="); queryBuilder.Append(HttpUtility.UrlEncode(kvp.Value)); queryBuilder.Append("&"); } queryBuilder.Remove(queryBuilder.Length - 1, 1); return queryBuilder.ToString(); } 

Usage example:

  Dictionary<string, string> parameterList = new Dictionary<string, string>(); parameterList.Add("auth_token", authCode); parameterList.Add("format", "json"); parameterList.Add("method", "facebook.auth.getSession"); string req = CreateHTTPParameterList(parameterList); 

I tried to copy / paste these codes from my old project. Hope this helps you.

0
source share

you have an error in the parameter that you send your secret code to generate_session_secret, it must be true or false

you set: new NameValuePair ("generate_session_secret", SECRET),

in your parameter there is a conflict which is set in post and the signature

0
source share

All Articles