13 changed files with 303 additions and 6 deletions
@ -0,0 +1,27 @@ |
|||||
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
|
||||
|
|
||||
|
namespace Infrastructure.Identity |
||||
|
{ |
||||
|
public class AppIdentityDbContext : IdentityDbContext<ApplicationUser> |
||||
|
{ |
||||
|
public AppIdentityDbContext(DbContextOptions<AppIdentityDbContext> options) |
||||
|
: base(options) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
protected override void OnModelCreating(ModelBuilder builder) |
||||
|
{ |
||||
|
base.OnModelCreating(builder); |
||||
|
// Customize the ASP.NET Identity model and override the defaults if needed.
|
||||
|
// For example, you can rename the ASP.NET Identity table names and more.
|
||||
|
// Add your customizations after calling base.OnModelCreating(builder);
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class ApplicationUser : IdentityUser |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,98 @@ |
|||||
|
using Microsoft.eShopWeb.Services; |
||||
|
using Microsoft.eShopWeb.ViewModels; |
||||
|
using Microsoft.AspNetCore.Hosting; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Microsoft.AspNetCore.Identity; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Infrastructure.Identity; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.Controllers |
||||
|
{ |
||||
|
public class AccountController : Controller |
||||
|
{ |
||||
|
private readonly UserManager<ApplicationUser> _userManager; |
||||
|
private readonly SignInManager<ApplicationUser> _signInManager; |
||||
|
private readonly string _externalCookieScheme; |
||||
|
|
||||
|
|
||||
|
public AccountController( |
||||
|
UserManager<ApplicationUser> userManager, |
||||
|
SignInManager<ApplicationUser> signInManager, |
||||
|
IOptions<IdentityCookieOptions> identityCookieOptions |
||||
|
|
||||
|
) |
||||
|
{ |
||||
|
_userManager = userManager; |
||||
|
_signInManager = signInManager; |
||||
|
_externalCookieScheme = identityCookieOptions.Value.ExternalCookieAuthenticationScheme; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//
|
||||
|
// GET: /Account/SignIn
|
||||
|
[HttpGet] |
||||
|
[AllowAnonymous] |
||||
|
public async Task<IActionResult> SignIn(string returnUrl = null) |
||||
|
{ |
||||
|
// Clear the existing external cookie to ensure a clean login process
|
||||
|
await HttpContext.Authentication.SignOutAsync(_externalCookieScheme); |
||||
|
|
||||
|
ViewData["ReturnUrl"] = returnUrl; |
||||
|
return View(); |
||||
|
} |
||||
|
|
||||
|
//
|
||||
|
// POST: /Account/SignIn
|
||||
|
[HttpPost] |
||||
|
[AllowAnonymous] |
||||
|
[ValidateAntiForgeryToken] |
||||
|
public async Task<IActionResult> SignIn(LoginViewModel model, string returnUrl = null) |
||||
|
{ |
||||
|
ViewData["ReturnUrl"] = returnUrl; |
||||
|
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(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); |
||||
|
if (result.Succeeded) |
||||
|
{ |
||||
|
//_logger.LogInformation(1, "User logged in.");
|
||||
|
return RedirectToLocal(returnUrl); |
||||
|
} |
||||
|
//if (result.RequiresTwoFactor)
|
||||
|
//{
|
||||
|
// return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
|
||||
|
//}
|
||||
|
if (result.IsLockedOut) |
||||
|
{ |
||||
|
//_logger.LogWarning(2, "User account locked out.");
|
||||
|
return View("Lockout"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ModelState.AddModelError(string.Empty, "Invalid login attempt."); |
||||
|
return View(model); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// If we got this far, something failed, redisplay form
|
||||
|
return View(model); |
||||
|
} |
||||
|
|
||||
|
private IActionResult RedirectToLocal(string returnUrl) |
||||
|
{ |
||||
|
if (Url.IsLocalUrl(returnUrl)) |
||||
|
{ |
||||
|
return Redirect(returnUrl); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return RedirectToAction(nameof(CatalogController.Index), "Home"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using Microsoft.eShopWeb.ApplicationCore.Entities; |
||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.ViewModels |
||||
|
{ |
||||
|
|
||||
|
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; } |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
@using System.Collections.Generic |
||||
|
@using Microsoft.AspNetCore.Http |
||||
|
@using Microsoft.AspNetCore.Http.Authentication |
||||
|
@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="Login" 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"); } |
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
@using Microsoft.AspNetCore.Identity |
||||
|
@*@inject IIdentityParser<ApplicationUser> UserManager*@ |
||||
|
|
||||
|
@if (Context.User.Identity.IsAuthenticated) |
||||
|
{ |
||||
|
<section class="col-lg-4 col-md-5 col-xs-12"> |
||||
|
<div class="esh-identity"> |
||||
|
<form asp-area="" asp-controller="Account" asp-action="SignOut" method="post" id="logoutForm" class="navbar-right"> |
||||
|
<section class="esh-identity-section"> |
||||
|
|
||||
|
@*<div class="esh-identity-name">@User.FindFirst(x => x.Type == "preferred_username").Value</div>*@ |
||||
|
<img class="esh-identity-image" src="~/images/arrow-down.png"> |
||||
|
</section> |
||||
|
|
||||
|
<section class="esh-identity-drop"> |
||||
|
|
||||
|
<a class="esh-identity-item" |
||||
|
asp-controller="Order" |
||||
|
asp-action="Index"> |
||||
|
|
||||
|
<div class="esh-identity-name esh-identity-name--upper">My orders</div> |
||||
|
<img class="esh-identity-image" src="~/images/my_orders.png"> |
||||
|
</a> |
||||
|
|
||||
|
<a class="esh-identity-item" |
||||
|
href="javascript:document.getElementById('logoutForm').submit()"> |
||||
|
|
||||
|
<div class="esh-identity-name esh-identity-name--upper">Log Out</div> |
||||
|
<img class="esh-identity-image" src="~/images/logout.png"> |
||||
|
</a> |
||||
|
</section> |
||||
|
</form> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="col-lg-1 col-xs-12"> |
||||
|
@*@await Component.InvokeAsync("Cart", new { user = UserManager.Parse(User) })*@ |
||||
|
</section> |
||||
|
|
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
<section class="col-lg-4 col-md-5 col-xs-12"> |
||||
|
<div class="esh-identity"> |
||||
|
<section class="esh-identity-section"> |
||||
|
<div class="esh-identity-item"> |
||||
|
|
||||
|
<a asp-area="" asp-controller="Account" asp-action="SignIn" class="esh-identity-name esh-identity-name--upper"> |
||||
|
Login |
||||
|
</a> |
||||
|
</div> |
||||
|
</section> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="col-lg-1 col-xs-12"></section> |
||||
|
} |
||||
@ -1,2 +1,3 @@ |
|||||
@using Microsoft.eShopWeb |
@using Microsoft.eShopWeb |
||||
|
@using Microsoft.eShopWeb.ViewModels |
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
||||
|
|||||
Loading…
Reference in new issue