Suggested Videos
Part 106 - ASP.NET Core google authentication - Setting up the UI | Text | Slides
Part 107 - ExternalLoginCallback action in asp.net core | Text | Slides
Part 108 - Register application with facebook | Text | Slides
In this video we will discuss, integrating Facebook authentication in asp.net core application.
Integrating external login providers like Google, Facebook, Microsoft etc is similar. So if we know how to integrate one external login providers, integrating others is similar.
We discussed integrating Google authentication in ASP.NET core in our previous videos in this ASP.NET core tutorial.
Enable Google authentication in ASP.NET Core
We configure and enable Google authentication in ConfigureServices() method of Startup class
We use AddGoogle() extension method to configure Google authentication in ASP.NET Core
Enable Facebook authentication in ASP.NET Core
Just like AddGoogle(), we have AddFacebook() extension method to configure Facebook authentication in ASP.NET core.
Login View
Since we have both Google and Facebook authentication integrated, we see the respective external login provider button automatically displayed on the Login view.
Redirect request to Facebook
When the Facebook button is clicked, our asp.net core application must redirect the request to Facebook for authentication. This is done by ExternalLogin() action in AccountController. The code in this method is written in a generic way, so it works for both Google and Facebook authentication.
Handle External Login Information received from Facebook
After the user is successfully authenticated by Facebook, the request is redirected back to our application, and the following ExternalLoginCallback() action in AccountController is executed. The code in this method is also written in a generic way, so it works for both Google and Facebook authentication.
Linking external accounts to a local user account
In this example, the user with email (PragimTest@gmail.com) has an account with both Facebook and Google. He can use either of these external accounts to log into our application.
We want to link both these external accounts (Facebook and Google) to the same local account in our asp.net core application. Local user accounts are in AspNetUsers table and external login accounts are in AspNetUserLogins table.
Notice, for the user with email (PragimTest@gmail.com), there are 2 rows in AspNetUserLogins table. One row is for the Facebook login and the other for Google login. Both these rows link to the one row in AspNetUsers table.
Part 106 - ASP.NET Core google authentication - Setting up the UI | Text | Slides
Part 107 - ExternalLoginCallback action in asp.net core | Text | Slides
Part 108 - Register application with facebook | Text | Slides
In this video we will discuss, integrating Facebook authentication in asp.net core application.
Integrating external login providers like Google, Facebook, Microsoft etc is similar. So if we know how to integrate one external login providers, integrating others is similar.
We discussed integrating Google authentication in ASP.NET core in our previous videos in this ASP.NET core tutorial.
- Part 105 - Registering asp.net core application with Google and obtaining client id and client secret
- Part 106 - Enable Google authentication in ASP.NET Core and setting up the UI
- Part 107 - Handling authenticated user information received from Google
Enable Google authentication in ASP.NET Core
We configure and enable Google authentication in ConfigureServices() method of Startup class
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = "XXXXX";
options.ClientSecret = "XXXXX";
});
}
{
services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = "XXXXX";
options.ClientSecret = "XXXXX";
});
}
We use AddGoogle() extension method to configure Google authentication in ASP.NET Core
Enable Facebook authentication in ASP.NET Core
Just like AddGoogle(), we have AddFacebook() extension method to configure Facebook authentication in ASP.NET core.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = "XXXXX";
options.ClientSecret = "XXXXX";
})
.AddFacebook(options =>
{
options.AppId = "XXXXX";
options.AppSecret = "XXXXX";
});
}
{
services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = "XXXXX";
options.ClientSecret = "XXXXX";
})
.AddFacebook(options =>
{
options.AppId = "XXXXX";
options.AppSecret = "XXXXX";
});
}
Login View
Since we have both Google and Facebook authentication integrated, we see the respective external login provider button automatically displayed on the Login view.
@model
LoginViewModel
@{
ViewBag.Title = "User Login";
}
<div class="row">
<div class="col-md-6">
<h1>Local
Account Login</h1>
<hr />
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label asp-for="RememberMe">
<input asp-for="RememberMe" />
@Html.DisplayNameFor(m => m.RememberMe)
</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
<div class="col-md-6">
<h1>External
Login</h1>
<hr />
@{
if (Model.ExternalLogins.Count == 0)
{
<div>No
external logins configured</div>
}
else
{
<form method="post" asp-action="ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl">
<div>
@foreach (var provider in Model.ExternalLogins)
{
<button type="submit" class="btn
btn-primary"
name="provider" value="@provider.Name"
title="Login usin your @provider.DisplayName
account">
@provider.DisplayName
</button>
}
</div>
</form>
}
}
</div>
</div>
Redirect request to Facebook
When the Facebook button is clicked, our asp.net core application must redirect the request to Facebook for authentication. This is done by ExternalLogin() action in AccountController. The code in this method is written in a generic way, so it works for both Google and Facebook authentication.
[AllowAnonymous]
[HttpPost]
public IActionResult ExternalLogin(string provider, string returnUrl)
{
var redirectUrl = Url.Action("ExternalLoginCallback", "Account",
new { ReturnUrl = returnUrl });
var properties =
signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return new ChallengeResult(provider, properties);
}
[HttpPost]
public IActionResult ExternalLogin(string provider, string returnUrl)
{
var redirectUrl = Url.Action("ExternalLoginCallback", "Account",
new { ReturnUrl = returnUrl });
var properties =
signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return new ChallengeResult(provider, properties);
}
Handle External Login Information received from Facebook
After the user is successfully authenticated by Facebook, the request is redirected back to our application, and the following ExternalLoginCallback() action in AccountController is executed. The code in this method is also written in a generic way, so it works for both Google and Facebook authentication.
[AllowAnonymous]
public async
Task<IActionResult>
ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
LoginViewModel loginViewModel = new LoginViewModel
{
ReturnUrl = returnUrl,
ExternalLogins = (await
signInManager.GetExternalAuthenticationSchemesAsync()).ToList()
};
if (remoteError != null)
{
ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}");
return View("Login", loginViewModel);
}
var info = await
signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ModelState.AddModelError(string.Empty, "Error loading external login information.");
return View("Login", loginViewModel);
}
var signInResult = await signInManager.ExternalLoginSignInAsync(info.LoginProvider,
info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
if (signInResult.Succeeded)
{
return LocalRedirect(returnUrl);
}
else
{
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
if (email != null)
{
var user = await
userManager.FindByEmailAsync(email);
if (user == null)
{
user = new ApplicationUser
{
UserName =
info.Principal.FindFirstValue(ClaimTypes.Email),
Email =
info.Principal.FindFirstValue(ClaimTypes.Email)
};
await userManager.CreateAsync(user);
}
await userManager.AddLoginAsync(user, info);
await signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
ViewBag.ErrorTitle = $"Email claim not received from: {info.LoginProvider}";
ViewBag.ErrorMessage = "Please contact support on Pragim@PragimTech.com";
return View("Error");
}
}
Linking external accounts to a local user account
In this example, the user with email (PragimTest@gmail.com) has an account with both Facebook and Google. He can use either of these external accounts to log into our application.
We want to link both these external accounts (Facebook and Google) to the same local account in our asp.net core application. Local user accounts are in AspNetUsers table and external login accounts are in AspNetUserLogins table.
Notice, for the user with email (PragimTest@gmail.com), there are 2 rows in AspNetUserLogins table. One row is for the Facebook login and the other for Google login. Both these rows link to the one row in AspNetUsers table.
If someone has a facebook account created by mobile number not gmail ...the system throw the below exception will not create a record in the asp.netUserLogins table.
ReplyDelete// If we cannot find the user email we cannot continue
ViewBag.ErrorTitle = $"Email claim not received from: {info.LoginProvider}";
ViewBag.ErrorMessage = "Please contact support on Mike@test.com";
please solve it..
signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
ReplyDeletefrom where you are geting signInManager ? its giving error