Skip to content

Commit

Permalink
Feature/admin (dotnet-architecture#831)
Browse files Browse the repository at this point in the history
* fix redirect to login for admin page
fix logout

* add admin part url

Co-authored-by: cedri <cedri@BAS>
michelcedric and cedri authored Dec 22, 2022
1 parent 2e6fc6c commit 61d2d6c
Showing 6 changed files with 49 additions and 17 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -47,7 +47,9 @@ The store's home page should look like this:

![eShopOnWeb home page screenshot](https://user-images.githubusercontent.com/782127/88414268-92d83a00-cdaa-11ea-9b4c-db67d95be039.png)

Most of the site's functionality works with just the web application running. However, the site's Admin page relies on Blazor WebAssembly running in the browser, and it must communicate with the server using the site's PublicApi web application. You'll need to also run this project. You can configure Visual Studio to start multiple projects, or just go to the PublicApi folder in a terminal window and run `dotnet run` from there. After that from the Web folder you should run `dotnet run --launch-profile Web`. Now you should be able to browse to `https://localhost:5001/`. Note that if you use this approach, you'll need to stop the application manually in order to build the solution (otherwise you'll get file locking errors).
Most of the site's functionality works with just the web application running. However, the site's Admin page relies on Blazor WebAssembly running in the browser, and it must communicate with the server using the site's PublicApi web application. You'll need to also run this project. You can configure Visual Studio to start multiple projects, or just go to the PublicApi folder in a terminal window and run `dotnet run` from there. After that from the Web folder you should run `dotnet run --launch-profile Web`. Now you should be able to browse to `https://localhost:5001/`. The admin part in Blazor is accessible to `https://localhost:5001/admin`

Note that if you use this approach, you'll need to stop the application manually in order to build the solution (otherwise you'll get file locking errors).

After cloning or downloading the sample you must setup your database.
To use the sample with a persistent database, you will need to run its Entity Framework Core migrations before you will be able to run the app.
2 changes: 1 addition & 1 deletion src/BlazorAdmin/CustomAuthStateProvider.cs
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ private async Task<ClaimsPrincipal> FetchUser()

if (user == null || !user.IsAuthenticated)
{
return null;
return new ClaimsPrincipal(new ClaimsIdentity());
}

var identity = new ClaimsIdentity(
2 changes: 1 addition & 1 deletion src/BlazorAdmin/Pages/Logout.razor
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@

protected override async Task OnInitializedAsync()
{
await HttpClient.PostAsync("Identity/Account/Logout", null);
await HttpClient.PostAsync("User/Logout", null);
await new Route(JSRuntime).RouteOutside("/Identity/Account/Login");
}

11 changes: 7 additions & 4 deletions src/BlazorAdmin/Shared/RedirectToLogin.razor
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
@inject NavigationManager Navigation
@using System.Web;

@inject NavigationManager Navigation
@inject IJSRuntime JsRuntime

@code {
protected override void OnInitialized()
{
Navigation.NavigateTo($"Identity/Account/Login?returnUrl=" +
$"/{Uri.EscapeDataString(Navigation.ToBaseRelativePath(Navigation.Uri))}");
{
var returnUrl = HttpUtility.UrlEncode($"/{Uri.EscapeDataString(Navigation.ToBaseRelativePath(Navigation.Uri))}");
JsRuntime.InvokeVoidAsync("location.replace", $"Identity/Account/Login?returnUrl={returnUrl}");
}
}
6 changes: 1 addition & 5 deletions src/Web/Areas/Identity/Pages/Account/Logout.cshtml.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
@@ -10,7 +7,6 @@
using Microsoft.eShopWeb.Infrastructure.Identity;
using Microsoft.eShopWeb.Web.Configuration;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;

namespace Microsoft.eShopWeb.Web.Areas.Identity.Pages.Account;

41 changes: 36 additions & 5 deletions src/Web/Controllers/UserController.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Security.Claims;
using BlazorShared.Authorization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.Infrastructure.Identity;
using Microsoft.eShopWeb.Web.Configuration;
using Microsoft.Extensions.Caching.Memory;

namespace Microsoft.eShopWeb.Web.Controllers;

@@ -14,10 +17,19 @@ namespace Microsoft.eShopWeb.Web.Controllers;
public class UserController : ControllerBase
{
private readonly ITokenClaimsService _tokenClaimsService;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ILogger<UserController> _logger;
private readonly IMemoryCache _cache;

public UserController(ITokenClaimsService tokenClaimsService)
public UserController(ITokenClaimsService tokenClaimsService,
SignInManager<ApplicationUser> signInManager,
ILogger<UserController> logger,
IMemoryCache cache)
{
_tokenClaimsService = tokenClaimsService;
_signInManager = signInManager;
_logger = logger;
_cache = cache;
}

[HttpGet]
@@ -26,6 +38,25 @@ public UserController(ITokenClaimsService tokenClaimsService)
public async Task<IActionResult> GetCurrentUser() =>
Ok(await CreateUserInfo(User));

[Route("Logout")]
[HttpPost]
[Authorize]
[AllowAnonymous]
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var userId = _signInManager.Context.User.Claims.First(c => c.Type == ClaimTypes.Name);
var identityKey = _signInManager.Context.Request.Cookies[ConfigureCookieSettings.IdentifierCookieName];
_cache.Set($"{userId.Value}:{identityKey}", identityKey, new MemoryCacheEntryOptions
{
AbsoluteExpiration = DateTime.Now.AddMinutes(ConfigureCookieSettings.ValidityMinutesPeriod)
});

_logger.LogInformation("User logged out.");
return Ok();
}

private async Task<UserInfo> CreateUserInfo(ClaimsPrincipal claimsPrincipal)
{
if (claimsPrincipal.Identity == null || claimsPrincipal.Identity.Name == null || !claimsPrincipal.Identity.IsAuthenticated)

0 comments on commit 61d2d6c

Please sign in to comment.