Suggested Videos
Part 103 - Custom authorization handler success vs failure | Text | Sldies
Part 104 - External identity providers in asp.net core | Text | Slides
Part 105 - Create google oauth credentials - Client Id and Client Secret | Text | Slides
In this video we will discuss integrating google authentication in asp.net core web application. We will set up the UI (ie. the User Interface) and also configure to redirect the request to Google when Signin with Google button is clicked.
In our next video, we will discuss handling the authenticated user identity received from Google.
We want our login page to look like the following.
Enable Google Authentication in ASP.NET Core
Include the following configuration in ConfigureServices() method of the Startup class. We discussed registering our application with Google and obtaining Client Id and Secret in our previous video.
The code required for Google authentication including this AddGoogle() method is present in Microsoft.AspNetCore.Authentication.Google nuget package. Since I am using ASP.NET Core 2.2, this package is automatically included in the project as part of the meta package. If you are using older versions of ASP.NET Core you have to manually install this nuget package.
LoginViewModel
The model for login view is LoginViewModel class. Include ReturnUrl and ExternalLogins properties.
ReturnUrl is the URL the user was trying to access before authentication. We preserve and pass it between requests using ReturnUrl property, so the user can be redirected to that URL upon successful authentication.
ExternalLogins property stores the list of external logins (like Facebook, Google etc) that are enabled in our application. You will better understand what this property does in just a bit, when we actually use it.
Login Action in AccountController
Login Page (Login.cshtml)
The following is the code specific to external login.
ExternalLogin action in AccountController
Part 103 - Custom authorization handler success vs failure | Text | Sldies
Part 104 - External identity providers in asp.net core | Text | Slides
Part 105 - Create google oauth credentials - Client Id and Client Secret | Text | Slides
In this video we will discuss integrating google authentication in asp.net core web application. We will set up the UI (ie. the User Interface) and also configure to redirect the request to Google when Signin with Google button is clicked.
In our next video, we will discuss handling the authenticated user identity received from Google.
We want our login page to look like the following.
Enable Google Authentication in ASP.NET Core
Include the following configuration in ConfigureServices() method of the Startup class. We discussed registering our application with Google and obtaining Client Id and Secret in our previous video.
services.AddAuthentication().AddGoogle(options =>
{
options.ClientId = "XXXXX";
options.ClientSecret = "YYYYY";
});
{
options.ClientId = "XXXXX";
options.ClientSecret = "YYYYY";
});
The code required for Google authentication including this AddGoogle() method is present in Microsoft.AspNetCore.Authentication.Google nuget package. Since I am using ASP.NET Core 2.2, this package is automatically included in the project as part of the meta package. If you are using older versions of ASP.NET Core you have to manually install this nuget package.
LoginViewModel
The model for login view is LoginViewModel class. Include ReturnUrl and ExternalLogins properties.
public class LoginViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me")]
public bool RememberMe { get; set; }
public string ReturnUrl { get; set; }
// AuthenticationScheme is in Microsoft.AspNetCore.Authentication namespace
public IList<AuthenticationScheme> ExternalLogins { get; set; }
}
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me")]
public bool RememberMe { get; set; }
public string ReturnUrl { get; set; }
// AuthenticationScheme is in Microsoft.AspNetCore.Authentication namespace
public IList<AuthenticationScheme> ExternalLogins { get; set; }
}
ReturnUrl is the URL the user was trying to access before authentication. We preserve and pass it between requests using ReturnUrl property, so the user can be redirected to that URL upon successful authentication.
ExternalLogins property stores the list of external logins (like Facebook, Google etc) that are enabled in our application. You will better understand what this property does in just a bit, when we actually use it.
Login Action in AccountController
- Populate ReturnUrl and ExternalLogins properties of LoginViewModel and then pass the instance to the view.
- GetExternalAuthenticationSchemesAsync() method of SignInManager service, returns the list of all configured external identity providers like (Google, Facebook etc).
- At the moment we only have one external identity provider configured and that is Google.
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl)
{
LoginViewModel model = new LoginViewModel
{
ReturnUrl = returnUrl,
ExternalLogins =
(await signInManager.GetExternalAuthenticationSchemesAsync()).ToList()
};
return View(model);
}
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl)
{
LoginViewModel model = new LoginViewModel
{
ReturnUrl = returnUrl,
ExternalLogins =
(await signInManager.GetExternalAuthenticationSchemesAsync()).ToList()
};
return View(model);
}
Login Page (Login.cshtml)
The following is the code specific to external login.
<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="Log in using
your @provider.DisplayName account">
@provider.DisplayName
</button>
}
</div>
</form>
- We are looping through each external login provider we have in Model.ExternalLogins
- For each external login provider a submit button is dynamically generated
- At the moment we only have one external identity provider configured and that is Google, so we get one Submit button.
- This submit button is inside a form. The form method attribute value is post and asp-action attribute value is ExternalLogin
- So when the submit button is clicked the form is posted to ExternalLogin action in AccountController
- The login provider is Google, so in the foreach loop, provider.Name returns Google.
- Since the button name is set to provider, asp.net core model binding maps the provider name which is Google to provider parameter on the ExternalLogin action.
@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="Log in using
your @provider.DisplayName account">
@provider.DisplayName
</button>
}
</div>
</form>
}
}
</div>
</div>
ExternalLogin action in AccountController
[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);
}
InvalidOperationException: No suitable constructor found for entity type 'AuthenticationScheme'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'name', 'displayName', 'handlerType' in 'AuthenticationScheme(string name, string displayName, Type handlerType)'.
ReplyDeletei have this problem can U help.
i got following error
ReplyDeleteOauth token endpoint failure
how can i solve this problem??
you have to made some modification while regestring service in startup.cs
Deletesee this link
https://github.com/dotnet/aspnetcore/issues/6486
I am having error :
ReplyDeleteError 400: redirect_uri_mismatch
The redirect URI in the request, https://localhost:44342/signin-google, does not match the ones authorized for the OAuth client. To update the authorized redirect URIs, visit: https://console.developers.google.com/apis/credentials/oauthclient/760664201936-qj63s17rb23la88e6nljsri55587a0i4.apps.googleusercontent.com?project=760664201936
Kindly tell what to do ?
Go to this link:
ReplyDeletehttps://console.developers.google.com/apis/credentials/oauthclient/760664201936-qj63s17rb23la88e6nljsri55587a0i4.apps.googleusercontent.com?project=760664201936
look for "Authorized redirect URis"
1. Click "Add Uri"
2. An empty textbox will appear
3. Type "https://localhost:44342/signin-google" into the empty textbox.
4. Click save.
if (Model.ExternalLogins.Count == 0)
ReplyDeleteI get this error when running the application
Can any one tell me what is the problem?
public async Task Login(string returnUrl)
ReplyDelete{
//setup login with providers
LoginVM model = new LoginVM
{
ReturnUrl = returnUrl,
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList()
};
var t = returnUrl;
ViewBag.newUserSWL = TempData["newUserSWL"] as string;
return View(model);
}
just asking why the return url back with null?
it's normal?
What is with this "signInManager". It throws error saying "The error signinmanager doesnot exists in the current context"?
ReplyDelete