.netauthenticationblazorasp.net-core-webapiopenid-connect

Passing authentication from Blazor to API, losing some claims


I have a Blazor Application with Authentication using OpenIdConnect.

Set up as follows:

.AddOpenIdConnect(options =>
{
    configuration.GetSection("Security").Bind(options);
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.ResponseType = OpenIdConnectResponseType.Code;
    options.SaveTokens = true;
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");
    options.UsePkce = true;
    options.GetClaimsFromUserInfoEndpoint = true;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = "name",
        RoleClaimType = "role"
    };
});

I also have an WebAPI, with authentication set up as follows:

services.AddAuthorization(options =>
{
    // Configure the default policy
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.Authority = configuration["Security:Authority"];
    });

In my Blazor Server application I call the API and add the access_token in the header.

    var accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync("access_token");

    request.Headers.Add("Authorization", $"Bearer {accessToken}");

This all works for the authentication part, I can see that user that is authenticated. But I am seeing very different claims in Blazor Server than in the WebAPI. In both places I am getting the user claims from the IHttpContextAccessor.

The Authority is the same in both the API and the application.

Any idea what's going on here?

Thank you!


Solution

  • openidconnect authentication will get idToken and accessToken. The blazor front-end with openidconnect will extract user claims from idToken itself. While api extra user claims from the accessToken it received.
    You could try observe the difference of them by jwt.io.

    .AddOpenIdConnect(options =>
    {
    ...
        // Save the tokens (including the ID token)
        options.SaveTokens = true;
    });
    

    Then

            var authResult = await HttpContextAccessor.HttpContext.AuthenticateAsync();
            IdToken = authResult.Properties?.GetTokenValue("id_token") ?? "ID Token not found";