Being able to have your users sign in to your website using their social media account is a great way to make your website more appealing.
Requiring a user to create a local account and confirm an email address might be enough for a user to go away. Especially if something goes wrong with the confirmation email. For example, if it takes a bit too long for the email to get to the user’s inbox.
Thankfully it’s really easy to setup an ASP.NET Core website with social login. This blog post is a step by step guide into how you can enable a user to login to your website using Facebook using just ASP.NET Core and then, using ASP.NET Core Identity.
Even though it’s very simple to setup social logins under the hood there’s a lot going on. If you interested in the nitty gritty details you should definitely read my other blog post External Login Providers in ASP.NET Core.
Step 0 – Registering your website with Facebook
Before you can have users sign in to your website using Facebook, Facebook needs to know about your website.
To do that go to Facebook’s developer page and click Register Now on “Become a Facebook Developer”.
There are a couple of steps in the registration process that you have to go through that will lead to you being asked to create an AppId:
An AppId is an identifier that Facebook uses to identify your website/web application. When your website redirects a user to Facebook for the user to sign in, the redirect will contain the AppId. This way Facebook can present a confirmation screen to your user with the application name.
So name your web application, and get an AppId:
You should see a screen now that on the top left corner has the AppId:
Click the Get Started button on the Facebook Login section:
Pick Web:
Add your website URL, you can use localhost for development.
You can ignore all the other steps after setting your website’s callback url. Those would only be required if we were to trigger the login process in JavaScript, which we are not.
Go to the Dashboard:
Make note of the App Secret:
You now have an App Id and an App Secret which is all you need to enable social logins using Facebook.
Setup Facebook login in your ASP.NET MVC
I’m going to describe the process of creating a new project from the command line. This way, the description is valid for whatever platform you are using.
Create a new MVC project
$ dotnet new -t mvc
Now add Nuget package for the cookie authentication middleware:
$ dotnet add package Microsoft.AspNetCore.Authentication.Cookies
And finally the Facebook authentication middleware:
$ dotnet add package Microsoft.AspNetCore.Authentication.Facebook
You now need to add and configure the cookie and the Facebook authentication middlewares in your ASP.NET application’s pipeline. To do add this to the Configure method in Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//...
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "ApplicationCookie",
AutomaticAuthenticate = true
});
app.UseFacebookAuthentication(new FacebookOptions
{
AuthenticationScheme = "Facebook",
AppId = "YOUR_APP_ID",
AppSecret = "YOUR_APP_SECRET",
SignInScheme = "ApplicationCookie"
});
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
The last thing you need to do is to add an action method that starts the process of signing your user in using Facebook. For example in the Account controller add this action method:
public IActionResult FacebookLogin(){
var authProperties = new AuthenticationProperties{
RedirectUri = Url.Action("Index", "Home")
};
return Challenge(authProperties, "Facebook");
}
If your run your web application now and go to /account/facebooklogin you should be able to login using Facebook.
If you want to check the claims that get added when your user signs in, add this to you Index.cshtml:
@if (User.Identity.IsAuthenticated){
@foreach(var claim in User.Claims){
<p><b>@claim.Type</b> - @claim.Value</p>
}
}else{
<p>User is not signed in</p>
}
NOTE: For an in-depth explanation of what a “Challenge” is and how the authentication middleware work you should read External Login Providers in ASP.NET Core.
Facebook login using ASP.NET Identity
The previous section described how you can set the Facebook authentication middelware log in a user “directly” by setting the SignInScheme to the cookie middleware that is set with AutomaticAuthenticate (if this sentence is confusing you really should stop and read External Login Providers in ASP.NET Core.
I’m going to assume that you have setup ASP.NET Identity in your project. If you haven’t done that yet here’s a good guide: ASP.NET Identity Core From Scratch.
Edit your Startup.cs class and add the Facebook authentication middleware:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//...
app.UseIdentity();
app.UseFacebookAuthentication(new FacebookOptions
{
AppId = "YOUR_APPID",
AppSecret = "YOUR_APP_SECRET",
AuthenticationScheme = "Facebook"
});
app.UseStaticFiles();
//app.UseMvc...
}
You can specify the SignInScheme as in the previous section. The main authentication scheme name (the one that actually adds the principal to HttpContext) is “Identity.Application”.
If you don’t specify a SignInScheme it will default to “Identity.External”, which corresponds to a cookie authentication middleware that is added by ASP.NET Identity and is configured with AutomaticAuthenticate=false. What that means is that it will not set the HttpContext.User, so it won’t log the user in.
The way you take advantage of an authentication middleware configured this way is to “manually” invoke it, so when configuring our challenge we’ll specify a redirect url to an controller action that does this. The reason for doing this is that in that controller action you can perform aditional steps, for example, create a local account for the user.
You can start the process of authenticating your users using Facebook the same way as in the previous section, however ASP.NET Identity’s SignInManager class has methods to do it. So if you want to use them, the action method that “issues” the challenge should look like this:
public IActionResult Login()
{
var properties = _signInManager.ConfigureExternalAuthenticationProperties("Facebook", Url.Action("ExternalLoginCallback", "Account"));
return Challenge(properties, "Facebook");
}
Here we added ExternalLoginCallback as the action in the AccountController where the user will be redirected to from Facebook after a successful authentication. Here’s a simplified version of that controller action:
public async Task<IActionResult> ExternalLoginCallback()
{
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
//info.Principal //the IPrincipal with the claims from facebook
//info.ProviderKey //an unique identifier from Facebook for the user that just signed in
//info.LoginProvider //a string with the external login provider name, in this case Facebook
//to sign the user in if there's a local account associated to the login provider
//var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
//result.Succeeded will be false if there's no local associated account
//to associate a local user account to an external login provider
//await _userInManager.AddLoginAsync(aUserYoullHaveToCreate, info);
return Redirect("~/");
}
And that’s it. Again, I recommend reading External Login Providers in ASP.NET Core because there’s a lot of nuance going on here. Also, if you need to enable HTTPS checkĀ HTTPS in ASP.NET Core from Scratch.