dotnet / dotnet/aspnetcore

Add an additional hook in Blazor WASM in the remote authentication flow before the AccountClaimsPrincipalFactory runs

Open
#67,187 0 comments 0 reactions 0 assignees View on GitHub
api-proposal api-suggestion area-blazor
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

## Background and Motivation

I am using Microsoft Entra to sign my users into an application. However, the database for my application contains the roles and permissions along with other important metadata that I need to make available at client-side to integrate with components like AuthorizeView and the Authorize attribute at page level, along with using things like user.IsInRole("someRole").

When I log in, I need a hook somewhere in the lifecycle that represents a point in the authentication process where I have access to the authentication token or ID token from Entra that contains my user's object ID so that I can make a call to my API and download some metadata about that user, store it somewhere like in sessionStorage, and then when my custom AccountClaimsPrincipalFactory logic fires and creates the ClaimsPrincipal, it can read from that storage location and update the ClaimsPrincipal being built up accordingly.

It is far too fragile to make the API call in the AccountClaimsPrincipalFactory and I often run into race conditions where the ClaimsPrincipal returned is incomplete, so I have had to put in a bunch of plumbing and extra parts on application startup to work around this missing hook in the authentication lifecycle.

The specific callback parameter type is less important than the lifecycle guarantee. The important requirement is that the callback runs after remote authentication has succeeded and before the client authentication state is published / before `AccountClaimsPrincipalFactory.CreateUserAsync(...)` is called.

The desired invariant is that application code can perform an awaited post-authentication bootstrap step before the first client-side `ClaimsPrincipal` is published to the app.

In my scenario, `AccountClaimsPrincipalFactory` should remain a deterministic mapper. It should not be responsible for acquiring tokens, calling APIs, handling token-interaction redirects, or deciding whether an incomplete principal is acceptable.

The missing hook would allow an app to:

1. Receive the authenticated remote account or enough token/account metadata to identify the user.
2. Perform an awaited bootstrap operation, such as calling an application API.
3. Persist bootstrap data in a client-side store.
4. Then allow `AccountClaimsPrincipalFactory` to build the principal from already-available data.

This would make role/claim integration with `AuthorizeView`, `[Authorize]`, and `ClaimsPrincipal.IsInRole(...)` reliable for applications where Entra authenticates the user but application roles/permissions come from an app database.

## Proposed API

```
namespace Microsoft.AspNetCore.Components.WebAssembly.Authentication;

public partial class RemoteAuthenticatorViewCore
{
+ [Parameter] public EventCallback OnBeforeBuildingClaimsPrincipal { get; set; }
}
```

(Please pardon me if the name isn't so great)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.