stephen776
stephen776

Reputation: 9234

What is the proper way to implement Form Authentication along side Facebook/Other authentication in ASP.NET MVC

I am building an application in ASP.NET MVC 3 in which I have implemented Forms authentication.

I would also like to give the user the option to Sign-up/log-in with their facebook account(and possibly other social accounts in the future.)

I am using the C# Facebook SDK

I have successfully implemented the facebook login workflow. Now my question is, how to handle mixing both Forms and Facebook Auth? I can't seem to find any sufficient examples of how to accomplish this.

In regards to my facebook implementation, I am requesting permission from the user for a non-expiring Auth Token which I will store in my database.

Upvotes: 2

Views: 1140

Answers (2)

Amar Palsapure
Amar Palsapure

Reputation: 9680

For this you will have to do something like this

  1. Create a custom class (CurrentIdentity) which implements IIdentity. Override .ToString() for this class, and so that you have some sort of serialized state of object. I had use "|" seperator. This string will be stored in encrypted cookie.
  2. Create a session cookie

    public static HttpCookie AuthCookie(CurrentIdentity identity) {
       //Create the Authticket, store it in Cookie and redirect user back
       FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,
                          identity.Name, DateTime.Now, DateTime.Now.AddHours(3), true, identity.ToString(), FormsAuthentication.FormsCookiePath);
       string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
       HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
       authCookie.Expires = authTicket.Expiration;
       return authCookie;
    }
    
  3. Add this cookie to response.

    HttpResponse res = HttpContext.Current.Response;
    res.Cookies.Add(Helper.AuthCookie(identity));
    res.Redirect(FormsAuthentication.GetRedirectUrl(identity.Name, true));
    res.End();
    
  4. Now in Gloabl.asax, inside *Application_AuthenticateRequest* read this cookie and populate your CurrentIdentity object, something like this.

    if (Request.IsAuthenticated == true) {
            // Extract the forms authentication cookie
            string cookieName = FormsAuthentication.FormsCookieName;
            HttpCookie authCookie = Context.Request.Cookies[cookieName];
    
            if (null == authCookie) {
                // There is no authentication cookie.
                return;
            }
            FormsAuthenticationTicket authTicket = null;
            try {
                authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            } catch (Exception) {
                // Log exception details (omitted for simplicity)
                return;
            }
    
            if (null == authTicket) {
                // Cookie failed to decrypt.
                return;
            }
            // When the ticket was created, the UserData property was assigned a
            // pipe delimited string of role names.
            string[] userInfo = authTicket.UserData.Split('|');
    
            // Create an Identity object
            FormsIdentity id = new FormsIdentity(authTicket);
            //Populate CurrentIdentity, from Serialized string
            CurrentIdentity currentIdentity = new CurrentIdentity(userInfo[0], userInfo[1], userInfo[2]);
            System.Security.Principal.GenericPrincipal principal = new System.Security.Principal.GenericPrincipal(currentIdentity, userInfo);
            Context.User = principal;
    }
    

This should solve your problem. I have implemented similar thing on my company's website.

Upvotes: 3

valch
valch

Reputation: 627

merge facebook authentication with your forms authentication. When user login using forms auth you create FormsAuthenticationTicket, when login from facebook also create FormsAuthenticationTicket

Upvotes: 0

Related Questions