Note that there are some explanatory texts on larger screens.

plurals
  1. POIntegrating Facebook chat
    primarykey
    data
    text
    <p>I have written a program to integrate Facebook user chat in C#, however I always get <code>&lt;failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"&gt;&lt;not-authorized/&gt;&lt;/failure&gt;</code> after sending the response to the server.</p> <p>I've checked the API key and the App secret, both of them are correct. It looks like I'm passing some wrong parameters to the server.</p> <p>Here is my code.</p> <pre><code>private void GetDetailsButton_Click(object sender, EventArgs e) { TcpClient FacebookClient = new TcpClient(); FacebookClient.Connect("chat.facebook.com", 5222); NetworkStream myns = FacebookClient.GetStream(); string xml = "&lt;?xml version='1.0'?&gt;" + "&lt;stream:stream " + "id='1' " + "to='chat.facebook.com' " + "xmlns='jabber:client' " + "xmlns:stream='http://etherx.jabber.org/streams' " + "version='1.0' &gt;"; StreamWriter mySw = new StreamWriter(myns); mySw.WriteLine(xml); //sending initial request mySw.Flush(); byte[] serverResponseByte = new byte[1024]; int myBytesRead = 0; StringBuilder myResponseAsSB = new StringBuilder(); //reading response from the server to see the supported authentication methods do { myBytesRead = myns.Read(serverResponseByte, 0, serverResponseByte.Length); myResponseAsSB.Append(System.Text.Encoding.UTF8.GetString(serverResponseByte, 0, myBytesRead)); } while (myns.DataAvailable); myResponseAsSB.Clear(); xml = "&lt;auth " + "xmlns='urn:ietf:params:xml:ns:xmpp-sasl' " + "mechanism='X-FACEBOOK-PLATFORM' /&gt;"; mySw.WriteLine(xml); mySw.Flush(); //sending response to server to use X-FACEBOOK-PLATFORM //reading challenge send by the server do { myBytesRead = myns.Read(serverResponseByte, 0, serverResponseByte.Length); myResponseAsSB.Append(System.Text.Encoding.UTF8.GetString(serverResponseByte, 0, myBytesRead)); } while (myns.DataAvailable); myResponseAsSB.Replace("&lt;challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"&gt;", ""); myResponseAsSB.Replace("&lt;/challenge&gt;", ""); //converting challenge string to normal string byte[] myregularstrigbytes = Convert.FromBase64String(myResponseAsSB.ToString()); string myregularstring = System.Text.Encoding.UTF8.GetString(myregularstrigbytes); //I've hardcoded the accesstoken here for testing purpose. string SessionKey = AccessToken.Split('|')[1]; string response = ComposeResponse(myregularstring); byte[] myResponseByte = Encoding.UTF8.GetBytes(response.ToString()); string myEncodedResponseToSend = Convert.ToBase64String(myResponseByte); xml = String.Format("&lt;response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"&gt;{0}&lt;/response&gt;", myEncodedResponseToSend); mySw.WriteLine(xml); mySw.Flush(); //sending the response to the server with my parameters myResponseAsSB.Clear(); //checking if authentication succeed do { myBytesRead = myns.Read(serverResponseByte, 0, serverResponseByte.Length); myResponseAsSB.Append(System.Text.Encoding.UTF8.GetString(serverResponseByte, 0, myBytesRead)); } while (myns.DataAvailable); MessageBox.Show(myResponseAsSB.ToString()); } private string ComposeResponse(string serverresponse) { string version = serverresponse.Split('&amp;')[0].Split('=')[1]; string method = serverresponse.Split('&amp;')[1].Split('=')[1]; string nonce = serverresponse.Split('&amp;')[2].Split('=')[1]; string SessionKey = AccessToken.Split('|')[1]; long callId = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; string sig = "api_key=" + appId + "call_id=" + callId + "method=" + method + "nonce=" + nonce + "session_key=" + SessionKey + "v=" + "1.0" + AppSecret; MD5 md = MD5.Create(); var hash = md.ComputeHash(Encoding.UTF8.GetBytes(sig)); sig = hash.Aggregate("", (current, b) =&gt; current + b.ToString("x2")); return "api_key=" + HttpUtility.UrlEncode(appId) + "&amp;call_id=" + HttpUtility.UrlEncode(callId) + "&amp;method=" + HttpUtility.UrlEncode(method) + "&amp;nonce=" + HttpUtility.UrlEncode(nonce) + "&amp;session_key=" + HttpUtility.UrlEncode(SessionKey) + "&amp;v=" + HttpUtility.UrlEncode("1.0") + "&amp;sig=" + HttpUtility.UrlEncode(sig); } </code></pre> <p>I've refereed to this articles <a href="http://www.ianquigley.com/A91_Facebook_Chat_Authentication_in_C.html" rel="nofollow noreferrer">Facebook Chat Authentication in C#</a> and <a href="http://aspnetpk.wikispaces.com/X-FACEBOOK-PLATFORM" rel="nofollow noreferrer">X-FACEBOOK-PLATFORM</a> and my application type is of Native/Desktop.</p> <p>Can some point me in the right direction?</p> <p><strong>Edit :</strong> I think the problem is while creating the signature, is there any way to verify the created signature?</p> <p><strong>Edit 1 :</strong> According to this <a href="https://stackoverflow.com/questions/3709505/facebook-chat-x-facebook-platform-authentication/4614905#4614905">SO answer</a> the access token contains the session key after the first | character and I could find the | character till 2 days ago, but now I can't find the | character in the access token, its really strange, so how do I find the session key now? (Or may be I should go to sleep now.)</p> <p><strong>Edit 2 :</strong> Its strange that I always got the access token in form of <code>&lt;appId&gt;|&lt;sessionKey&gt;|&lt;digest&gt;</code> for native/desktop application. I did further searching and found out that the session key needs to be extracted from <a href="http://developers.facebook.com/docs/reference/rest/auth.promoteSession/" rel="nofollow noreferrer">auth.promoteSession</a> legacy api and encode the parameters using <code>HttpUtility.UrlEncode</code> instead of <code>HttpUtility.HtmlEncode</code>. </p> <p>Now I've hard coded the Access token (verified it in the <a href="https://developers.facebook.com/tools/debug" rel="nofollow noreferrer">Access Token Debugger</a>), the session key, App key and app secret still I get the same error <code>&lt;failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"&gt;&lt;not-authorized/&gt;&lt;/failure&gt;</code> </p> <p><strong>Edit 3 :</strong> I have been banging my head over a week and still this doesn't work, but today I found a update in the <a href="http://developers.facebook.com/docs/chat/" rel="nofollow noreferrer">documentation</a> which says <code>Note that this needs to be over TLS (Transport Layer Security) or you'll get an error.</code> I guess I need to modify my code accordingly.</p> <p><strong>Edit 4 :</strong> I've tried out the code in the documentation and found that the value of <code>$SESSION_XML</code> should be</p> <pre><code>$SESSION_XML = '&lt;iq type="set" id="4"&gt;'. '&lt;session xmlns="urn:ietf:params:xml:ns:xmpp-session"/&gt;&lt;/iq&gt;'; </code></pre> <p>I will post the C# code once I finish converting it.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload