diff --git a/aspnetcore/blazor/security/blazor-web-app-with-windows-authentication.md b/aspnetcore/blazor/security/blazor-web-app-with-windows-authentication.md index 0268b5e19377..a8120b0a1aee 100644 --- a/aspnetcore/blazor/security/blazor-web-app-with-windows-authentication.md +++ b/aspnetcore/blazor/security/blazor-web-app-with-windows-authentication.md @@ -5,7 +5,7 @@ description: Learn how to secure a Blazor Web App with Windows Authentication. monikerRange: '>= aspnetcore-9.0' ms.author: wpickett ms.custom: mvc -ms.date: 03/25/2025 +ms.date: 09/11/2025 uid: blazor/security/blazor-web-app-windows-authentication --- # Secure an ASP.NET Core Blazor Web App with Windows Authentication @@ -88,32 +88,48 @@ The authorization policy is enforced by the `LocalAccountOnly` component.

``` -The `UserClaims` component lists the user's claims, which includes the user's Windows security identifiers (SIDs). +The `UserClaims` component lists the user's claims and roles, including the user's Windows security identifiers (SIDs) with SID translations. `Components/Pages/UserClaims.razor`: ```razor @page "/user-claims" @using System.Security.Claims -@using Microsoft.AspNetCore.Authorization -@attribute [Authorize] +@using System.Security.Principal +@using Microsoft.AspNetCore.Components.QuickGrid + +User Claims & Roles + +

User Claims & Roles

-User Claims + + + + + + + -

User Claims

+

User Roles

-@if (claims.Any()) +@if (roles.Any()) { } +else +{ +

No roles available.

+} @code { - private IEnumerable claims = []; + private IQueryable claims = Enumerable.Empty().AsQueryable(); + private IEnumerable roles = Enumerable.Empty(); + PaginationState pagination = new PaginationState { ItemsPerPage = 10 }; [CascadingParameter] private Task? AuthState { get; set; } @@ -126,7 +142,38 @@ The `UserClaims` component lists the user's claims, which includes the user's Wi } var authState = await AuthState; - claims = authState.User.Claims; + + claims = authState.User.Claims.AsQueryable(); + + roles = authState.User.Claims + .Where(claim => claim.Type == ClaimTypes.Role) + .Select(claim => claim.Value); + } + + private string GetClaimAsHumanReadable(Claim claim) + { + if (!OperatingSystem.IsWindows() || + claim.Type is not (ClaimTypes.PrimarySid or ClaimTypes.PrimaryGroupSid + or ClaimTypes.GroupSid)) + { + // We're either not on Windows or not dealing with a SID Claim that + // can be translated + return string.Empty; + } + + SecurityIdentifier sid = new SecurityIdentifier(claim.Value); + + try + { + // Throw an exception if the SID can't be translated + var account = sid.Translate(typeof(NTAccount)); + + return account.ToString(); + } + catch (IdentityNotMappedException) + { + return "Could not be mapped"; + } } } ``` diff --git a/aspnetcore/tutorials/first-web-api.md b/aspnetcore/tutorials/first-web-api.md index 50a12500dbe0..25f8223fff51 100644 --- a/aspnetcore/tutorials/first-web-api.md +++ b/aspnetcore/tutorials/first-web-api.md @@ -79,7 +79,7 @@ A NuGet package must be added to support the database used in this tutorial. dotnet new webapi --use-controllers -o TodoApi cd TodoApi dotnet add package Microsoft.EntityFrameworkCore.InMemory - code -r ../TodoApi + code -r . ``` These commands: diff --git a/aspnetcore/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie90/Models/SeedData.cs b/aspnetcore/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie90/Models/SeedData.cs index 72cad5065bbb..8ccae189cdb2 100644 --- a/aspnetcore/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie90/Models/SeedData.cs +++ b/aspnetcore/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie90/Models/SeedData.cs @@ -34,15 +34,6 @@ public static void Initialize(IServiceProvider serviceProvider) Rating = "R" }, - new Movie - { - Title = "When Harry Met Sally", - ReleaseDate = DateTime.Parse("1989-2-12"), - Genre = "Romantic Comedy", - Price = 7.99M, - Rating = "R" - }, - new Movie { Title = "Ghostbusters ", diff --git a/aspnetcore/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie90/Pages/Movies/Details.cshtml b/aspnetcore/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie90/Pages/Movies/Details.cshtml index da3cce998a77..2758850085f4 100644 --- a/aspnetcore/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie90/Pages/Movies/Details.cshtml +++ b/aspnetcore/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie90/Pages/Movies/Details.cshtml @@ -35,6 +35,9 @@
@Html.DisplayFor(model => model.Movie.Price)
+
+ @Html.DisplayNameFor(model => model.Movie.Rating) +
@Html.DisplayFor(model => model.Movie.Rating)