The Visual Studio Facebook template and Facebook Page tabs

By

Campaigns and contests on Facebook are still hot and we actually have a team that specializes in these types of applications using PHP & MySQL. PHP makes sense considering the size of these apps, their short delivery time and the PHP SDK and documentation provided by Facebook.

In a recent campaign however I was asked to develop an app in ASP.NET so I decided to give it a try using the Facebook template for ASP.NET MVC 4 in Visual Studio 2012.

The Facebook template to the rescue

Although I have little but some experience with Facebook apps I really didn’t want to spend too much time on authentication and authorization which I know can be a bit of a hassle. I won’t go into too much detail but it involves some redirecting, retrieving a user’s access token/code and eventually obtaining a signed request.

For this reason I got started using the Facebook template which primarily supports Facebook canvas applications which are slightly different to the Page tab application I will be creating. But I soon found out the template does a really great job in facilitating the authorization process!

In fact the template just lets you focus on creating your (MVC) app as it allows you to decorate your controller actions with an attribute you can provide with the Facebook permissions the action requires. Facebook authorization is thus handled on a per request basis and the user will be prompted for any additional permissions that are required for that specific action.

public class HomeController : Controller
{
    [FacebookAuthorize("email", "user_photos")]
    public async Task Index(FacebookContext context)
    {
        if (ModelState.IsValid)
        {
            var user = await context.Client.GetCurrentUserAsync();
            return View(user);
        }

        return View("Error");
    }
}

The MVC model binder passes in a Facebook context object which contains information about the request such as the access token, signed request, user id and a Facebook client. The client allows you to fetch additional user data from Facebook which requires a web service call and hence the use of asynchronous methods.

For further information I would really recommend reading this excellent tutorial which contains a bunch of useful information concerning the Facebook template as well as configuring the canvas app on Facebook and configuring your local machine's IIS with SSL.

But what about running the app in a Page tab?

When running the application in a Facebook page tab the authentication process is somewhat different. You will need to specify the page name in the Facebook login URL and your app should authenicate the user just once during the first request.

If you are familiar with ASP.NET MVC you probably have already guessed the authorization magic happens in an action filter which uses the authorization attributes to collect the required permissions, handle authorization and provide the MVC model minder with the context: the FacebookAuthorizeFilter.

Unfortunately the action filter uses several private methods and an internal helper class but as the source is open we can just copy/paste whatever we need into a custom action filter.

Creating the Oauth request

The OAuth request is to be constructed differently in the OnAuthorization method and instead of requesting the login URL from the Facebook client I have used the helper method shown below. Note that it requires an extra app setting containing the name of the Facebook page.


        public virtual Uri GetLoginUrl(string requiredPermissionString)
        {
            var tabRedirectUrl = String.Format(
                "https://www.facebook.com/{0}?sk=app_{1}",
                ConfigurationManager.AppSettings["TabPageName"],
                _config.AppId
            );

            var loginUrl = String.Format(
                "https://www.facebook.com/dialog/oauth?client_id={0}&redirect_uri={1}&scope={2}",
                _config.AppId,
                HttpUtility.UrlEncode(tabRedirectUrl),
                requiredPermissionString ?? "");

            return new Uri(loginUrl);
        }

Persisting the signed request

To prevent the action filter from authorizing permissions for each request I decided to persist the signed request in the session during the initial request and retrieve it from the session during succeeding requests.

OnAuthorization:

			if (signedRequest != null)
			{
				userId = signedRequest.user_id;
				accessToken = signedRequest.oauth_token;
				filterContext.HttpContext.Session["signedRequest"] = signedRequest;
			}

FacebookRequestHelpers.GetSignedRequest:

			string rawSignedRequest = context.Request.Form[SignedRequestKey] ?? context.Request.QueryString[SignedRequestKey];
			object signedRequest = null;
			if (!String.IsNullOrEmpty(rawSignedRequest))
			{
				signedRequest = parseSignedRequest(rawSignedRequest);
				context.Items.Add(ParsedSignedRequestKey, signedRequest);
			}
			else if (context.Session["signedRequest"] != null)
			{
				signedRequest = context.Session["signedRequest"];
				context.Items.Add(ParsedSignedRequestKey, signedRequest);
			}

Registering the custom action filter

In order to have the Facebook template actually use your custom action filter you will need to register it in the FacebookConfig class in the App_Start folder.

	public static class FacebookConfig
	{
		public static void Register(FacebookConfiguration configuration)
		{
			configuration.LoadFromAppSettings();
			GlobalFilters.Filters.Add(new FacebookTabAuthorizeFilter(configuration));
		}
	}

Configuring a P3P header

As Page tab applications are loaded within an Iframe and since we are now using a session cookie an unpleasant side effect is having the application to send a P3P header with each HTTP request to avoid IE from blocking (session) cookies. Fortunately the P3P header can be easily configured in the web.config.

	<system.webServer>
		<httpProtocol>
			<customHeaders>
				<add name="P3P" value='CP="CAO PSA OUR"'/>
			</customHeaders>
		</httpProtocol>
	</system.webServer>

Conclusion

The Facebook template will get you started quickly and it lets you focus on creating your canvas app without having to worry about Facebook authorization and permissions.

Authorization within page tab applications is handled somewhat differently and it does not share the idea of requesting permissions on a per action/request basis.

The workaround I have used may not be ideal as it depends upon session state but it’s the best I could come up with in short notice and it did allow me to use the Facebook template in a page tab scenario.

If you have come up with a different solution, I’d love to hear about it!

This entry was tagged with ASP.NET, Facebook, Social Media, Uncategorized, Web development. Bookmark the permalink.

Leave a Reply