From 270875115b67d0437fa7461106b798faae3188f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 05:33:49 +0000 Subject: [PATCH 1/4] Initial plan From c2e33cb7ab129fecb4c3a8960562b1af5e999d0f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 05:35:50 +0000 Subject: [PATCH 2/4] Add header comments and update SKILL.md to reference NuGet package Co-authored-by: jmprieur <13203188+jmprieur@users.noreply.github.com> --- .../BlazorAuthenticationChallengeHandler.cs | 4 +++ ...ginLogoutEndpointRouteBuilderExtensions.cs | 4 +++ .../entra-id-aspire-authentication/SKILL.md | 32 +++++++------------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/skills/entra-id-aspire-authentication/BlazorAuthenticationChallengeHandler.cs b/.github/skills/entra-id-aspire-authentication/BlazorAuthenticationChallengeHandler.cs index cce77251d..7cdfec903 100644 --- a/.github/skills/entra-id-aspire-authentication/BlazorAuthenticationChallengeHandler.cs +++ b/.github/skills/entra-id-aspire-authentication/BlazorAuthenticationChallengeHandler.cs @@ -1,3 +1,7 @@ +// NOTE: This file is included in Microsoft.Identity.Web package (v3.3.0+). +// This copy is maintained for AI skill reference and documentation purposes. +// For production use, reference the NuGet package directly. + using System.Security.Claims; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; diff --git a/.github/skills/entra-id-aspire-authentication/LoginLogoutEndpointRouteBuilderExtensions.cs b/.github/skills/entra-id-aspire-authentication/LoginLogoutEndpointRouteBuilderExtensions.cs index e2b447896..46d8103e6 100644 --- a/.github/skills/entra-id-aspire-authentication/LoginLogoutEndpointRouteBuilderExtensions.cs +++ b/.github/skills/entra-id-aspire-authentication/LoginLogoutEndpointRouteBuilderExtensions.cs @@ -1,3 +1,7 @@ +// NOTE: This file is included in Microsoft.Identity.Web package (v3.3.0+). +// This copy is maintained for AI skill reference and documentation purposes. +// For production use, reference the NuGet package directly. + using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; diff --git a/.github/skills/entra-id-aspire-authentication/SKILL.md b/.github/skills/entra-id-aspire-authentication/SKILL.md index 11d3d16c1..2c33a4780 100644 --- a/.github/skills/entra-id-aspire-authentication/SKILL.md +++ b/.github/skills/entra-id-aspire-authentication/SKILL.md @@ -105,13 +105,12 @@ Get-ChildItem -Recurse -Filter "Program.cs" | ForEach-Object { - [ ] Step 2.1: Add Microsoft.Identity.Web package - [ ] Step 2.2: Update appsettings.json with AzureAd and scopes - [ ] Step 2.3: Update Program.cs with OIDC, token acquisition, and **BlazorAuthenticationChallengeHandler** -- [ ] Step 2.4: Copy LoginLogoutEndpointRouteBuilderExtensions.cs from skill folder (adds incremental consent support) -- [ ] Step 2.5: Copy BlazorAuthenticationChallengeHandler.cs from skill folder -- [ ] Step 2.6: Create UserInfo.razor component (LOGIN BUTTON) -- [ ] Step 2.7: Update MainLayout.razor to include UserInfo -- [ ] Step 2.8: Update Routes.razor with AuthorizeRouteView -- [ ] Step 2.9: Store client secret in user-secrets -- [ ] Step 2.10: Add try/catch with ChallengeHandler on **every page calling APIs** +- [ ] Step 2.4: Verify Microsoft.Identity.Web version includes Blazor helpers (v3.3.0+) +- [ ] Step 2.5: Create UserInfo.razor component (LOGIN BUTTON) +- [ ] Step 2.6: Update MainLayout.razor to include UserInfo +- [ ] Step 2.7: Update Routes.razor with AuthorizeRouteView +- [ ] Step 2.8: Store client secret in user-secrets +- [ ] Step 2.9: Add try/catch with ChallengeHandler on **every page calling APIs** --- @@ -241,17 +240,11 @@ app.MapGroup("/authentication").MapLoginAndLogout(); app.Run(); ``` -**2.4 Copy `LoginLogoutEndpointRouteBuilderExtensions.cs` from skill folder:** +**2.4 Blazor authentication helpers:** -Copy the `LoginLogoutEndpointRouteBuilderExtensions.cs` file from this skill's folder to the Web project root. +These helpers ship in the `Microsoft.Identity.Web` NuGet package (version 3.3.0+). Simply add `using Microsoft.Identity.Web;` — no file copying required. -> **AGENT:** The file is located at `./LoginLogoutEndpointRouteBuilderExtensions.cs`. The namespace is `Microsoft.Identity.Web` so no changes are needed — it provides the `MapLoginAndLogout()` extension method with support for incremental consent and Conditional Access. - -**2.5 Copy `BlazorAuthenticationChallengeHandler.cs` from skill folder:** - -Copy the `BlazorAuthenticationChallengeHandler.cs` file from this skill's folder to the Web project root. - -> **AGENT:** The file is located at `./BlazorAuthenticationChallengeHandler.cs`. The namespace is `Microsoft.Identity.Web` so no changes are needed — it will be available once Microsoft.Identity.Web is referenced. +> **AGENT:** The `LoginLogoutEndpointRouteBuilderExtensions` class provides the `MapLoginAndLogout()` extension method with support for incremental consent and Conditional Access. The `BlazorAuthenticationChallengeHandler` class handles authentication challenges in Blazor Server components. Both are now included in Microsoft.Identity.Web and are automatically available once you reference the package. **2.6 Create UserInfo Component (`Components/UserInfo.razor`) — THE LOGIN BUTTON:** @@ -499,12 +492,12 @@ else | ApiService | `appsettings.json` | AzureAd config (ClientId, TenantId) | | Web | `Program.cs` | OIDC + token acquisition + challenge handler registration | | Web | `appsettings.json` | AzureAd config + downstream API scopes | -| Web | `LoginLogoutEndpointRouteBuilderExtensions.cs` | Login/logout with incremental consent support (**copy from skill**) | -| Web | `BlazorAuthenticationChallengeHandler.cs` | Reusable auth challenge handler (**copy from skill**) | | Web | `Components/UserInfo.razor` | **Login/logout button UI** | | Web | `Components/Layout/MainLayout.razor` | Include UserInfo in layout | | Web | `Components/Routes.razor` | AuthorizeRouteView for protected pages | +> **Note:** `LoginLogoutEndpointRouteBuilderExtensions` and `BlazorAuthenticationChallengeHandler` are now included in the Microsoft.Identity.Web NuGet package (v3.3.0+). Simply reference the package and use `using Microsoft.Identity.Web;` — no file copying required. + --- ## Post-Implementation Verification @@ -522,12 +515,11 @@ else - [ ] Web `Program.cs` has `AddMicrosoftIdentityWebApp` and `AddMicrosoftIdentityMessageHandler` - [ ] Web `Program.cs` has `AddScoped()` - [ ] Web `appsettings.json` has `AzureAd` and scope configuration - - [ ] Web has `LoginLogoutEndpointRouteBuilderExtensions.cs` (with incremental consent params) - - [ ] Web has `BlazorAuthenticationChallengeHandler.cs` - [ ] Web has `Components/UserInfo.razor` (**LOGIN BUTTON**) - [ ] Web `MainLayout.razor` includes `` - [ ] Web `Routes.razor` uses `AuthorizeRouteView` - [ ] **Every page calling protected APIs** has try/catch with `ChallengeHandler.HandleExceptionAsync(ex)` + - [ ] Microsoft.Identity.Web package version is 3.3.0 or higher 3. **AGENT: Inform user of next step:** > "✅ **Phase 1 complete!** Authentication code is in place. The app will **build** but **won't run** until app registrations are configured. From 3eda62f6c5cb1afc09e8869f14a08008e22748a8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 05:36:47 +0000 Subject: [PATCH 3/4] Update aspire.md to reference Blazor helpers from NuGet package Co-authored-by: jmprieur <13203188+jmprieur@users.noreply.github.com> --- docs/frameworks/aspire.md | 41 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/docs/frameworks/aspire.md b/docs/frameworks/aspire.md index 7bf0f267b..4f20cb936 100644 --- a/docs/frameworks/aspire.md +++ b/docs/frameworks/aspire.md @@ -281,7 +281,9 @@ app.UseAuthorization(); app.MapGroup("/authentication").MapLoginAndLogout(); ``` -> ⚠️ **Don't forget:** Copy the helper files (`BlazorAuthenticationChallengeHandler.cs`, `LoginLogoutEndpointRouteBuilderExtensions.cs`) and create `UserInfo.razor`. See [Part 2](#part-2-configure-blazor-frontend-for-authentication) for details. +> ⚠️ **Don't forget:** Create `UserInfo.razor` for the login button. See [Part 2](#part-2-configure-blazor-frontend-for-authentication) for details. +> +> **Note:** `BlazorAuthenticationChallengeHandler` and `LoginLogoutEndpointRouteBuilderExtensions` ship in Microsoft.Identity.Web (v3.3.0+) — no file copying required. **That's it!** The `MicrosoftIdentityMessageHandler` automatically acquires and attaches tokens, and `BlazorAuthenticationChallengeHandler` handles consent/Conditional Access challenges. @@ -298,14 +300,14 @@ app.MapGroup("/authentication").MapLoginAndLogout(); | | `.csproj` | Add `Microsoft.Identity.Web` | | **Web** | `Program.cs` | OIDC auth, token acquisition, BlazorAuthenticationChallengeHandler | | | `appsettings.json` | Azure AD config, downstream API scopes | -| | `.csproj` | Add `Microsoft.Identity.Web` | -| | `LoginLogoutEndpointRouteBuilderExtensions.cs` | Login/logout with incremental consent *(copy from skill)* | -| | `BlazorAuthenticationChallengeHandler.cs` | Auth challenge handler *(copy from skill)* | +| | `.csproj` | Add `Microsoft.Identity.Web` (v3.3.0+) | | | `Components/UserInfo.razor` | **Login button UI** *(new file)* | | | `Components/Layout/MainLayout.razor` | Include UserInfo component | | | `Components/Routes.razor` | AuthorizeRouteView for protected pages | | | Pages calling APIs | Try/catch with ChallengeHandler | +> **Note:** `LoginLogoutEndpointRouteBuilderExtensions` and `BlazorAuthenticationChallengeHandler` are included in Microsoft.Identity.Web (v3.3.0+) — no file copying required. + --- ## What you'll build & how it works @@ -726,22 +728,16 @@ builder.Services.AddHttpClient(client => -### 2.4: Copy helper files from skill folder - -The authentication implementation requires two helper files. **Copy these from the skill folder** rather than creating them manually: +### 2.4: Blazor authentication helpers -```powershell -# From your solution root, copy the helper files -$skillPath = ".github/skills/entra-id-aspire-authentication" -Copy-Item "$skillPath/LoginLogoutEndpointRouteBuilderExtensions.cs" "MyService.Web/" -Copy-Item "$skillPath/BlazorAuthenticationChallengeHandler.cs" "MyService.Web/" -``` +These helpers ship in the **Microsoft.Identity.Web** NuGet package (version **3.3.0+**). Simply add `using Microsoft.Identity.Web;` — no file copying required. -> 💡 **Tip:** These files are in the `Microsoft.Identity.Web` namespace, so they're available once you reference the package. Eventually they will -> ship in the Microsoft.Identity.Web NuGet packge. +> 💡 **Note:** `LoginLogoutEndpointRouteBuilderExtensions` provides the `MapLoginAndLogout()` extension method, and `BlazorAuthenticationChallengeHandler` handles authentication challenges. Both are now included in the package and are automatically available once you reference it.
-📄 View LoginLogoutEndpointRouteBuilderExtensions.cs +📄 View LoginLogoutEndpointRouteBuilderExtensions.cs (Reference) + +> **Note:** This implementation ships in **Microsoft.Identity.Web v3.3.0+**. The code below is shown for reference only — use the NuGet package in production. This enhanced version supports **incremental consent** and **Conditional Access** via query parameters: @@ -844,7 +840,9 @@ public static class LoginLogoutEndpointRouteBuilderExtensions
-📄 View BlazorAuthenticationChallengeHandler.cs +📄 View BlazorAuthenticationChallengeHandler.cs (Reference) + +> **Note:** This implementation ships in **Microsoft.Identity.Web v3.3.0+**. The code below is shown for reference only — use the NuGet package in production. This handler manages authentication challenges in Blazor Server components: @@ -1194,12 +1192,11 @@ Use this checklist to verify all steps are complete: - [ ] Added `.RequireAuthorization()` to protected endpoints ### Web/Blazor project -- [ ] Added `Microsoft.Identity.Web` package +- [ ] Added `Microsoft.Identity.Web` package (v3.3.0+) - [ ] Updated `appsettings.json` with `AzureAd` and `WeatherApi` sections - [ ] Updated `Program.cs` with OIDC, token acquisition - [ ] Added `AddScoped()` -- [ ] Copied `LoginLogoutEndpointRouteBuilderExtensions.cs` from skill folder -- [ ] Copied `BlazorAuthenticationChallengeHandler.cs` from skill folder +- [ ] Verified Blazor helpers are available (included in package v3.3.0+) - [ ] Created `Components/UserInfo.razor` (**THE LOGIN BUTTON**) - [ ] Updated `MainLayout.razor` to include `` - [ ] Updated `Routes.razor` with `AuthorizeRouteView` @@ -1574,10 +1571,12 @@ This guide has companion **AI Skills** for GitHub Copilot, Claude, and other AI | **entra-id-aspire-authentication** | Phase 1: Add authentication code | [SKILL.md](../../.github/skills/entra-id-aspire-authentication/SKILL.md) | | **entra-id-aspire-provisioning** | Phase 2: Create app registrations | [SKILL.md](../../.github/skills/entra-id-aspire-provisioning/SKILL.md) | -The authentication skill folder also contains **ready-to-copy helper files**: +The authentication skill folder also contains **reference implementations of helper files**: - `BlazorAuthenticationChallengeHandler.cs` - Handles incremental consent and Conditional Access - `LoginLogoutEndpointRouteBuilderExtensions.cs` - Enhanced login/logout endpoints +> **Note:** These helpers are included in Microsoft.Identity.Web (v3.3.0+). The skill folder copies are maintained for AI skill reference and documentation purposes. + See the [Skills README](../../.github/skills/README.md) for installation instructions. --- From 9ee9a233d9af31e0014f3aa7094919ab95091c94 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 05:38:03 +0000 Subject: [PATCH 4/4] Fix remaining reference to skill folder helper files Co-authored-by: jmprieur <13203188+jmprieur@users.noreply.github.com> --- docs/frameworks/aspire.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frameworks/aspire.md b/docs/frameworks/aspire.md index 4f20cb936..10178db37 100644 --- a/docs/frameworks/aspire.md +++ b/docs/frameworks/aspire.md @@ -530,7 +530,7 @@ curl -H "Authorization: Bearer " https://localhost:/weatherforecast ## Part 2: Configure Blazor frontend for authentication -> 📍 **Still in Phase 1** — This part completes the code implementation. You'll need the helper files from the skill folder. +> 📍 **Still in Phase 1** — This part completes the code implementation. The Blazor helpers are included in Microsoft.Identity.Web (v3.3.0+). The Blazor Server app uses **Microsoft.Identity.Web** to: - Sign users in with OIDC