Search This Blog

Tuesday, September 13, 2011

Facebook OAuth authentication for WPF application in C#

Facebook uses OAuth 2.0 for authentication and authorization.This authentication is used to access Facebook data using their Graph API. To access data from Facebook, 3 steps - user authentication, app authorization and app authentication are involved. At the end of the third step, user access token is issued. This is explained in detail here.

The prerequisite from Facebook, for fetching the data using Facebook graph API is, getting the client id. Go to https://developers.facebook.com/apps and click on Create New App button. Just walk through the next button clicks and complete it. Once it is completed, make a note of the App ID.

Next step is to decide what set of permissions are required for the app. http://developers.facebook.com/docs/reference/api/permissions/ link explains in detail about the set of available permissions. They accept comma delimited permissions.

For desktop applications "http://www.facebook.com/connect/login_success.html" is the redirect uri. For web apps, redirect uri has to be mentioned in the Facebook app.

Navigate the browser control to this url - https://graph.facebook.com/oauth/authorize?client_id=<<App Id>>&redirect_uri=<<redirect uri>>&scope=<<comma delimited permissions>>&type=user_agent&display=popup.

The browser control gets navigated to http://www.facebook.com/connect/login_success.html#access_token=<<Access token>>&expires_in=<<Expires in>>&code=<<code>>.

In WPF, there is problem with the System.Windows.Controls.WebBrowser. In the url, the characters after # is ignored. System.Windows.Forms.WebBrowser can capture it. So host it under System.Windows.Forms.Integration.WindowsFormsHost. This comes as handy workaround for it. The complete code looks like this

xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:win="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

    <my:WindowsFormsHost>
            <win:WebBrowser x:Name="browser" Navigated="browser_Navigated"></win:WebBrowser>
        </my:WindowsFormsHost>

I have created a sample WPF application which takes the App Id & comma delimited scope as the input and returns Access token & Expiration time in seconds.The Sample project can be downloaded from the link - http://aravindks.codeplex.com/

5 comments:

  1. hello my name is Adan, i'm very interesed in your application but i don't know which data type is scope, can you show me an example of scope data?

    ReplyDelete
  2. Thanks for showing interest in my application. Scope can be a comma separated string type. Basically scope refers to the set of permissions which your app requires. The set of permissions (scope) can be obtained more in detail from this link - http://developers.facebook.com/docs/reference/api/permissions/

    I hope this clears all your doubt. I have sample application posted in this link - http://aravindks.codeplex.com/

    ReplyDelete
  3. Hello Aravind,

    thanks for your article. I'm creating a WPF app (.net 3.5 in VS 2008) that uses facebook c# SDK.
    Using System.Windows.Forms.WebBrowser, everything works like a charm, but.... But I would like that my app requires everytime To login.
    I tried almost everything: deleting cookies, a redirect to the logout page, but I can't find any solution.
    It's seems that webbrowser controls keeps a cache, and doesn't require login anymore.
    Any suggestion is appreciated.

    Superpole

    ReplyDelete
    Replies
    1. Hi Superpole,

      To clear session (such as HttpOnly cookies), you can use InternetSetOption() from wininet.dll.

      private const int INTERNET_OPTION_END_BROWSER_SESSION = 42;

      [DllImport("wininet.dll", SetLastError = true)]
      private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);

      and use this method whenever need to clear session.

      InternetSetOption(IntPtr.Zero, INTERNET_OPTION_END_BROWSER_SESSION, IntPtr.Zero, 0);
      webBrowser1.Document.Window.Navigate(url);

      This should help you.

      Delete
  4. This comment has been removed by the author.

    ReplyDelete