9 changed files with 215 additions and 2 deletions
@ -0,0 +1,21 @@ |
|||
using System; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Identity.UI; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
[assembly: HostingStartup(typeof(Microsoft.eShopWeb.Web.Areas.Identity.IdentityHostingStartup))] |
|||
namespace Microsoft.eShopWeb.Web.Areas.Identity |
|||
{ |
|||
public class IdentityHostingStartup : IHostingStartup |
|||
{ |
|||
public void Configure(IWebHostBuilder builder) |
|||
{ |
|||
builder.ConfigureServices((context, services) => { |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
@page |
|||
@model LoginModel |
|||
|
|||
@{ |
|||
ViewData["Title"] = "Log in"; |
|||
} |
|||
|
|||
<h2>@ViewData["Title"]</h2> |
|||
<div class="container" account-login-container> |
|||
<div class="row"> |
|||
<div class="col-md-12"> |
|||
<section> |
|||
<form method="post"> |
|||
<h4>Use a local account to log in.</h4> |
|||
<hr /> |
|||
<div asp-validation-summary="All" class="text-danger"></div> |
|||
<div class="form-group"> |
|||
<label asp-for="Input.Email"></label> |
|||
<input asp-for="Input.Email" class="form-control" /> |
|||
<span asp-validation-for="Input.Email" class="text-danger"></span> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label asp-for="Input.Password"></label> |
|||
<input asp-for="Input.Password" class="form-control" /> |
|||
<span asp-validation-for="Input.Password" class="text-danger"></span> |
|||
</div> |
|||
<div class="form-group"> |
|||
<div class="checkbox"> |
|||
<label asp-for="Input.RememberMe"> |
|||
<input asp-for="Input.RememberMe" /> |
|||
@Html.DisplayNameFor(m => m.Input.RememberMe) |
|||
</label> |
|||
</div> |
|||
</div> |
|||
<div class="form-group"> |
|||
<button type="submit" class="btn btn-default">Log in</button> |
|||
</div> |
|||
<div class="form-group"> |
|||
<p> |
|||
<a asp-page="./ForgotPassword">Forgot your password?</a> |
|||
</p> |
|||
<p> |
|||
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a> |
|||
</p> |
|||
</div> |
|||
<p> |
|||
Note that for demo purposes you don't need to register and can login with these credentials: |
|||
</p> |
|||
<p> |
|||
User: <b>demouser@microsoft.com</b> |
|||
</p> |
|||
<p> |
|||
Password: <b>Pass@word1</b> |
|||
</p> |
|||
</form> |
|||
</section> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
@section Scripts { |
|||
<partial name="_ValidationScriptsPartial" /> |
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Areas.Identity.Pages.Account |
|||
{ |
|||
[AllowAnonymous] |
|||
public class LoginModel : PageModel |
|||
{ |
|||
private readonly SignInManager<ApplicationUser> _signInManager; |
|||
private readonly ILogger<LoginModel> _logger; |
|||
|
|||
public LoginModel(SignInManager<ApplicationUser> signInManager, ILogger<LoginModel> logger) |
|||
{ |
|||
_signInManager = signInManager; |
|||
_logger = logger; |
|||
} |
|||
|
|||
[BindProperty] |
|||
public InputModel Input { get; set; } |
|||
|
|||
public IList<AuthenticationScheme> ExternalLogins { get; set; } |
|||
|
|||
public string ReturnUrl { get; set; } |
|||
|
|||
[TempData] |
|||
public string ErrorMessage { get; set; } |
|||
|
|||
public class InputModel |
|||
{ |
|||
[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 async Task OnGetAsync(string returnUrl = null) |
|||
{ |
|||
if (!string.IsNullOrEmpty(ErrorMessage)) |
|||
{ |
|||
ModelState.AddModelError(string.Empty, ErrorMessage); |
|||
} |
|||
|
|||
returnUrl = returnUrl ?? Url.Content("~/"); |
|||
|
|||
// Clear the existing external cookie to ensure a clean login process
|
|||
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); |
|||
|
|||
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); |
|||
|
|||
ReturnUrl = returnUrl; |
|||
} |
|||
|
|||
public async Task<IActionResult> OnPostAsync(string returnUrl = null) |
|||
{ |
|||
returnUrl = returnUrl ?? Url.Content("~/"); |
|||
|
|||
if (ModelState.IsValid) |
|||
{ |
|||
// This doesn't count login failures towards account lockout
|
|||
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
|
|||
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true); |
|||
if (result.Succeeded) |
|||
{ |
|||
_logger.LogInformation("User logged in."); |
|||
return LocalRedirect(returnUrl); |
|||
} |
|||
if (result.RequiresTwoFactor) |
|||
{ |
|||
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe }); |
|||
} |
|||
if (result.IsLockedOut) |
|||
{ |
|||
_logger.LogWarning("User account locked out."); |
|||
return RedirectToPage("./Lockout"); |
|||
} |
|||
else |
|||
{ |
|||
ModelState.AddModelError(string.Empty, "Invalid login attempt."); |
|||
return Page(); |
|||
} |
|||
} |
|||
|
|||
// If we got this far, something failed, redisplay form
|
|||
return Page(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1 @@ |
|||
@using Microsoft.eShopWeb.Web.Areas.Identity.Pages.Account |
|||
@ -0,0 +1,18 @@ |
|||
<environment include="Development"> |
|||
<script src="~/Identity/lib/jquery-validation/dist/jquery.validate.js"></script> |
|||
<script src="~/Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script> |
|||
</environment> |
|||
<environment exclude="Development"> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js" |
|||
asp-fallback-src="~/Identity/lib/jquery-validation/dist/jquery.validate.min.js" |
|||
asp-fallback-test="window.jQuery && window.jQuery.validator" |
|||
crossorigin="anonymous" |
|||
integrity="sha384-rZfj/ogBloos6wzLGpPkkOr/gpkBNLZ6b6yLy4o+ok+t/SAKlL5mvXLr0OXNi1Hp"> |
|||
</script> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.9/jquery.validate.unobtrusive.min.js" |
|||
asp-fallback-src="~/Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" |
|||
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive" |
|||
crossorigin="anonymous" |
|||
integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds"> |
|||
</script> |
|||
</environment> |
|||
@ -0,0 +1,5 @@ |
|||
@using Microsoft.AspNetCore.Identity |
|||
@using Microsoft.eShopWeb.Web.Areas.Identity |
|||
@using Microsoft.eShopWeb.Infrastructure.Identity |
|||
@namespace Microsoft.eShopWeb.Web.Areas.Identity.Pages |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
Loading…
Reference in new issue