I want to allow users to sign up to my website using Facebook. I already use the JS SDK on the client side for authentication and authorization and the C# sdk on the server side
Facebook uses OAuth 2.0. The only way you can authenticate a user is by sending the user to a Facebook login page, and redirecting back using their OAuth implementation. This essentually provides you with a user specific time limited access_token
.
It isn't really a good fit for MembershipProviders, although it is possible to request offline_access permission which allows you perform authorized requests on behalf of the user at any time. The user has to agree to this. Facebook T&Cs are that you can't deny the user access to your site for not agreeing to extended permissions, so this again breaks the model.
I'm not saying it's not possible, it just doesn't seem worth the effort. You would be better off just using the forms authentication parts without membership. Setting up auth cookie & validating auth cookie based on facebook access_token
.
For authentication with Facebook look at open source .NET OAuth libraries. I also wrote an article of Facebook integration which shows some integration techniques (and opinions) here.
Update based on you amended question:
Use Forms authentication cookie to store the unique identifier of your choosing (Facebook username for instance). You can also store the current access_token
in the cookie.
if (OAuth.ValidateUser(username, user_access_token))
{
// store the user access token to make it available on each request
string userData = user_access_token;
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // ticket version
username, // authenticated username
DateTime.Now, // issueDate
DateTime.Now.AddMinutes(30), // expiryDate
isPersistent, // true to persist across browser sessions
userData, // can be used to store additional user data
FormsAuthentication.FormsCookiePath); // the path for the cookie
// Encrypt the ticket using the machine key
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
// Add the cookie to the request to save it
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket));
// Your redirect logic
Response.Redirect(FormsAuthentication.GetRedirectUrl(username, isPersistent));
}
Then override authenticate request to read the cookie and retrieve the user details.
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookie[FormsAuthentication.FormsCookieName];
if(authCookie != null)
{
//Extract the forms authentication cookie
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// If caching roles in userData field then extract
string user_access_token = authTicket.UserData;
// Create the IIdentity instance, maybe use a custom one
// possibly retrieve extra data from database or whatever here
IIdentity id = new FacebookIdentity( authTicket, user_access_token );
// Create the IPrinciple instance
IPrincipal principal = new GenericPrincipal(id, new string[]{});
// Set the context user
Context.User = principal;
}
}
Then in your code on each request:
var username = Context.User.Identity.Username;
// implement as an extension method on IIdentity which types to
// FacebookIdentity to get user_access_token
var user_access_token = Context.User.Identity.Access_Token;