committed by
GitHub
14 changed files with 257 additions and 92 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"; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
<div class="container account-login-container"> |
||||
|
<h2>@ViewData["Title"]</h2> |
||||
|
<div class="row"> |
||||
|
<div class="col-md-12"> |
||||
|
<section> |
||||
|
<form method="post"> |
||||
|
<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 |
||||
@ -1,59 +0,0 @@ |
|||||
@model LoginViewModel |
|
||||
@{ |
|
||||
ViewData["Title"] = "Log in"; |
|
||||
} |
|
||||
<div class="brand-header-block"> |
|
||||
<ul class="container"> |
|
||||
@*<li><a asp-area="" asp-controller="Account" asp-action="Register">REGISTER</a></li>*@ |
|
||||
<li class="active" style="margin-right: 65px;">LOGIN</li> |
|
||||
</ul> |
|
||||
</div> |
|
||||
<div class="container account-login-container"> |
|
||||
<div class="row"> |
|
||||
<div class="col-md-12"> |
|
||||
<section> |
|
||||
<form asp-controller="Account" asp-action="SignIn" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal"> |
|
||||
<h4>ARE YOU REGISTERED?</h4> |
|
||||
<div asp-validation-summary="All" class="text-danger"></div> |
|
||||
<div class="form-group"> |
|
||||
<label asp-for="Email" class="control-label form-label"></label> |
|
||||
<input asp-for="Email" class="form-control form-input form-input-center" /> |
|
||||
<span asp-validation-for="Email" class="text-danger"></span> |
|
||||
</div> |
|
||||
<div class="form-group"> |
|
||||
<label asp-for="Password" class="control-label form-label"></label> |
|
||||
<input asp-for="Password" class="form-control form-input form-input-center" /> |
|
||||
<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> |
|
||||
<div class="form-group"> |
|
||||
<button type="submit" class="btn btn-default btn-brand btn-brand-big"> LOG IN </button> |
|
||||
</div> |
|
||||
<p> |
|
||||
<a asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]" class="text">Register as a new user?</a> |
|
||||
</p> |
|
||||
<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 { |
|
||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } |
|
||||
} |
|
||||
@ -1 +1 @@ |
|||||
.esh-app-footer{background-color:#000;border-top:1px solid #eee;margin-top:2.5rem;padding-bottom:2.5rem;padding-top:2.5rem;width:100%;}.esh-app-footer-brand{height:50px;width:230px;}.esh-app-header{margin:15px;} |
.esh-app-footer{background-color:#000;border-top:1px solid #eee;margin-top:2.5rem;padding-bottom:2.5rem;padding-top:2.5rem;width:100%;bottom:0;}.esh-app-footer-brand{height:50px;width:230px;}.esh-app-header{margin:15px;}.esh-app-wrapper{display:flex;min-height:100vh;flex-direction:column;justify-content:space-between;} |
||||
Loading…
Reference in new issue