Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a Facebook signed_request in .NET?

I'm using Facebook as a login provider for my web application (ASP.NET MVC).

My login works similar to another StackOverflow post How to securely authorize a user via Facebook's Javascript SDK. I also share the user's concerns.

The flow for my login is as Follows:

1. The user presses the login button.

Log in with Facebook

2. The user must accept the app.

Accepting the app

3. A javascript callback retrieves the response.

var authResponse = response.authResponse;

Object returned:

{
    accessToken: "...",
    expiresIn: 1234,
    signedRequest: "...",
    userID: "123456789"
}

I've heard that I can used the signed_request to validate the user's request, but all the examples online are for PHP. How do I do this in .NET?

like image 826
Rowan Freeman Avatar asked Feb 05 '14 13:02

Rowan Freeman


1 Answers

To compile Rowan's answer into its final code:

public static string DecodeSignedRequest(string signed_request)
{
    try
    {
        if (signed_request.Contains("."))
        {
            string[] split = signed_request.Split('.');

            string signatureRaw = FixBase64String(split[0]);
            string dataRaw = FixBase64String(split[1]);

            // the decoded signature
            byte[] signature = Convert.FromBase64String(signatureRaw);

            byte[] dataBuffer = Convert.FromBase64String(dataRaw);

            // JSON object
            string data = Encoding.UTF8.GetString(dataBuffer);

            byte[] appSecretBytes = Encoding.UTF8.GetBytes(app_secret);
            System.Security.Cryptography.HMAC hmac = new System.Security.Cryptography.HMACSHA256(appSecretBytes);
            byte[] expectedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(split[1]));
            if (expectedHash.SequenceEqual(signature))
            {
                return data;
            }
        }
    }
    catch
    {
        // error
    }
    return "";
}

private static string FixBase64String(string str)
{
    while (str.Length % 4 != 0)
    {
        str = str.PadRight(str.Length + 1, '=');
    }
    return str.Replace("-", "+").Replace("_", "/");
}

Thanks Rowan!

like image 145
Doug S Avatar answered Jan 03 '23 12:01

Doug S