Skip to content

Blazor WASM hosted on IIS 10 log in exception for some users. #23215

@Kazbek

Description

@Kazbek

Describe the bug

I`m using blazor webassembly with authorization on IdentityServer (as from the box). Now app published on IIS 10. And 4 user of 200+ registered when login has this error:
image

Some of them use Google Chrome, some Mozilla Firefox

To Reproduce

I can't reproduce that. For them reauthorize doesn`t help (also cache clearing) but they can log in from other devices.

Exceptions

When I login myself (withoit error). Browser console log: All Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1] have index '[1]'.

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
      Authorization was successful.
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.LogicalHandler[100]
      Start processing HTTP request POST .../Course.Course/GetCourseIndex
blazor.webassembly.js:1 info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
      Authorization was successful.
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.LogicalHandler[100]
      Start processing HTTP request POST .../UserInfo.UserInfo/GetCurrentUserShortName
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.ClientHandler[100]
      Sending HTTP request POST .../Course.Course/GetCourseIndex
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.ClientHandler[100]
      Sending HTTP request POST .../UserInfo.UserInfo/GetCurrentUserShortName
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.ClientHandler[101]
      Received HTTP response after 243.53ms - OK
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.LogicalHandler[101]
      End processing HTTP request after 489.965ms - OK
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.ClientHandler[101]
      Received HTTP response after 379.355ms - OK
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.LogicalHandler[101]
      End processing HTTP request after 784.4049ms - OK
blazor.webassembly.js:1 info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
      Authorization was successful.

When I log in as user who has error (I don`t have error but anyway) some of Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] (have number 2 and failed).

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
      Authorization was successful.
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.LogicalHandler[100]
      Start processing HTTP request POST .../Course.Course/GetCourseIndex
blazor.webassembly.js:1 info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed.
blazor.webassembly.js:1 info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
      Authorization was successful.
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.LogicalHandler[100]
      Start processing HTTP request POST .../UserInfo.UserInfo/GetCurrentUserShortName
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.ClientHandler[100]
      Sending HTTP request POST .../Course.Course/GetCourseIndex
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.ClientHandler[100]
      Sending HTTP request POST .../UserInfo.UserInfo/GetCurrentUserShortName
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.ClientHandler[101]
      Received HTTP response after 203.9549ms - OK
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.LogicalHandler[101]
      End processing HTTP request after 511.6849ms - OK
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.ClientHandler[101]
      Received HTTP response after 233.73ms - OK
blazor.webassembly.js:1 info: System.Net.Http.HttpClient.AuthCenter.gRPC.LogicalHandler[101]
      End processing HTTP request after 437.115ms - OK
blazor.webassembly.js:1 info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed.

But on screenshot from the user I see only failed with number 2 and none of DefaultAuthorizationService[1] (I apologize for the quality of the screenshot, it was sent by the user):
image

A bit of code

Program.cs

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");

builder.Services.AddHttpClient("AuthCenter.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

builder.Services.AddHttpClient("AuthCenter.gRPC", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("AuthCenter.ServerAPI"));

builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
builder.Services.AddApiAuthorization(options =>
{
    options.UserOptions.RoleClaim = "role";
}).AddAccountClaimsPrincipalFactory<RolesClaimsPrincipalFactory>(); ;

builder.Services.AddScoped<ICurrentUserService, CurrentUserService>();

builder.Services.AddScoped(services =>
{
    var httpClient = services.GetRequiredService<IHttpClientFactory>().CreateClient("AuthCenter.gRPC");
    var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient });
    return new UserInfo.UserInfoClient(channel);
});

builder.Services.AddScoped(services =>
{
    var httpClient = services.GetRequiredService<IHttpClientFactory>().CreateClient("AuthCenter.gRPC");
    var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient });
    return new Course.CourseClient(channel);
});

builder.Services.AddScoped(services =>
{
    var httpClient = services.GetRequiredService<IHttpClientFactory>().CreateClient("AuthCenter.gRPC");
    var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient });
    return new StudyGroups.StudyGroupsClient(channel);
});

builder.Services.AddBlazoredModal();
builder.Services.AddBlazoredToast();
builder.Services.AddScoped<IToastService, ToastService>();

await builder.Build().RunAsync();

RolesClaimsPrincipalFactory.cs

public class RolesClaimsPrincipalFactory : AccountClaimsPrincipalFactory<RemoteUserAccount>
{
    public RolesClaimsPrincipalFactory(IAccessTokenProviderAccessor accessor) : base(accessor)
    {
    }

    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(RemoteUserAccount account, RemoteAuthenticationUserOptions options)
    {
        var user = await base.CreateUserAsync(account, options);
        if (user.Identity.IsAuthenticated)
        {
            var identity = (ClaimsIdentity)user.Identity;
            var roleClaims = identity.FindAll(identity.RoleClaimType);
            if (roleClaims != null && roleClaims.Any())
            {
                foreach (var existingClaim in roleClaims)
                {
                    identity.RemoveClaim(existingClaim);
                }

                var rolesElem = account.AdditionalProperties[identity.RoleClaimType];
                if (rolesElem is JsonElement roles)
                {
                    if (roles.ValueKind == JsonValueKind.Array)
                    {
                        foreach (var role in roles.EnumerateArray())
                        {
                            identity.AddClaim(new Claim(options.RoleClaim, role.GetString()));
                        }
                    }
                    else
                    {
                        identity.AddClaim(new Claim(options.RoleClaim, roles.GetString()));
                    }
                }
            }
        }

        return user;
    }
}

Further technical details

image

dotnet --info
Џ ЄҐв SDK ¤«п .NET Core (®ва ¦ ойЁ© «оЎ®© global.json):
Version: 3.1.301
Commit: 7feb845744

‘।  ўлЇ®«­Ґ­Ёп:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.1.301\

Host (useful for support):
Version: 3.1.5
Commit: 65cd789777

.NET Core SDKs installed:
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.402 [C:\Program Files\dotnet\sdk]
2.1.403 [C:\Program Files\dotnet\sdk]
2.1.502 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.2.101 [C:\Program Files\dotnet\sdk]
3.1.101 [C:\Program Files\dotnet\sdk]
3.1.301 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

VisualStudio.16.Release/16.6.2+30204.135

ASP.NET and Web Tools 2019 16.6.948.25768
ASP.NET and Web Tools 2019

ASP.NET Core Razor Language Services 16.1.0.2020603+b3ac44798c16fff5b95dbcfe62dea84aa9a1bd72
Provides languages services for ASP.NET Core Razor.

I’m sorry if I did something wrong, for a week now we can’t find the cause of this problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    affected-very-fewThis issue impacts very few customersarea-blazorIncludes: Blazor, Razor ComponentsbugThis issue describes a behavior which is not expected - a bug.feature-blazor-deploymentIssues related to deploying Blazorfeature-blazor-wasmThis issue is related to and / or impacts Blazor WebAssemblyinvestigateseverity-majorThis label is used by an internal tool

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions