diff --git a/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/EqDemo.BlazorWasm.AdhocReporting.Client.csproj b/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/EqDemo.BlazorWasm.AdhocReporting.Client.csproj index 757d9614..8ef8b788 100644 --- a/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/EqDemo.BlazorWasm.AdhocReporting.Client.csproj +++ b/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/EqDemo.BlazorWasm.AdhocReporting.Client.csproj @@ -1,18 +1,18 @@ - + - net6.0 + net8.0 EqDemo.Client enable enable - - - - - + + + + + diff --git a/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/HostAuthenticationStateProvider.cs b/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/HostAuthenticationStateProvider.cs new file mode 100644 index 00000000..a79a412f --- /dev/null +++ b/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/HostAuthenticationStateProvider.cs @@ -0,0 +1,61 @@ +using System.Net; +using System.Net.Http.Json; +using System.Security.Claims; + +using Microsoft.AspNetCore.Components.Authorization; + +namespace EqDemo.Client; + +/// +/// Resolves the current user's authentication state by calling a small endpoint +/// on the server (which authenticates the request via the ASP.NET Core Identity +/// auth cookie). Replaces the OIDC-based remote authentication state provider +/// that came with Microsoft.AspNetCore.ApiAuthorization.IdentityServer. +/// +public sealed class HostAuthenticationStateProvider : AuthenticationStateProvider +{ + private const string AuthenticationType = "Cookies"; + + private static readonly AuthenticationState Anonymous = + new(new ClaimsPrincipal(new ClaimsIdentity())); + + private readonly HttpClient _http; + + public HostAuthenticationStateProvider(HttpClient http) + { + _http = http; + } + + public override async Task GetAuthenticationStateAsync() + { + try + { + var response = await _http.GetAsync("_auth/me"); + if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden) + { + return Anonymous; + } + + response.EnsureSuccessStatusCode(); + + var info = await response.Content.ReadFromJsonAsync(); + if (info is null || !info.IsAuthenticated) + { + return Anonymous; + } + + var claims = (info.Claims ?? Array.Empty()) + .Select(c => new Claim(c.Type, c.Value)); + var identity = new ClaimsIdentity(claims, AuthenticationType, ClaimTypes.Name, ClaimTypes.Role); + return new AuthenticationState(new ClaimsPrincipal(identity)); + } + catch (HttpRequestException) + { + return Anonymous; + } + } + + private sealed record AuthInfo(bool IsAuthenticated, AuthClaim[]? Claims); + + private sealed record AuthClaim(string Type, string Value); +} diff --git a/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/Pages/Authentication.razor b/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/Pages/Authentication.razor index 6c743567..eb3d9ffd 100644 --- a/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/Pages/Authentication.razor +++ b/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/Pages/Authentication.razor @@ -1,7 +1,23 @@ @page "/authentication/{action}" -@using Microsoft.AspNetCore.Components.WebAssembly.Authentication - +@inject NavigationManager Navigation -@code{ +@code { [Parameter] public string? Action { get; set; } + + protected override void OnInitialized() + { + // The legacy OIDC client-side authentication flow has been replaced with + // server-side cookie auth via ASP.NET Core Identity Razor Pages. Redirect + // legacy /authentication/{action} URLs to the new endpoints. + var target = Action switch + { + "login" => "Identity/Account/Login", + "register" => "Identity/Account/Register", + "logout" => "Identity/Account/Logout", + "profile" => "Identity/Account/Manage", + _ => "/" + }; + + Navigation.NavigateTo(target, forceLoad: true); + } } diff --git a/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/Pages/Reports.razor b/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/Pages/Reports.razor index ac5ce0a1..b594c3d6 100644 --- a/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/Pages/Reports.razor +++ b/AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/Pages/Reports.razor @@ -1,14 +1,11 @@ @page "/reports" @using Microsoft.AspNetCore.Authorization -@using Microsoft.AspNetCore.Components.WebAssembly.Authentication -@using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal @attribute [Authorize] @implements IAsyncDisposable @inject IJSRuntime JSRuntime @inject NavigationManager NavigationManager @inject AuthenticationStateProvider AuthenticationStateProvider -@inject IAccessTokenProviderAccessor AccessTokenProviderAccessor