Stanislav Čaja
Stanislav Čaja

Reputation: 108

Blazor webassembly use API from http.sys with windows authentication results in unauthorized

I am runnning client blazor wasm on https://localhost:5001/ and an API server hosted with http.sys on https://localhost:44302/. I have set windows authentication for http.sys as described in here https://learn.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-5.0&tabs=visual-studio#httpsys

Now when using HttpClient on Blazor wasm and reaching a controller or hub with [Authorize] I instantly get Unauthorized.

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Response status code does not indicate success: 401 (Unauthorized).
System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized) with exception
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.NegotiateAsync(Uri url, HttpClient httpClient, ILogger logger, CancellationToken cancellationToken)

I would like to know why there is no popup dialog with setting the credentials with this setup.

In contrast when I have Blazor wasm hosted with IIS it works that the browser popup login shows up.

Thank you so much, for your answers.

Upvotes: 2

Views: 906

Answers (1)

Stanislav Čaja
Stanislav Čaja

Reputation: 108

I solved it. So basically the problem is with the request which is being send.

Solution 1 - Manually add for every request BrowserRequestCredentials.Include

var httpRequest = new HttpRequestMessage();
        
httpRequest.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);

Solution 2 - Create Delegating Handler reference here https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/signalr?view=aspnetcore-5.0&pivots=webassembly

    public class IncludeRequestCredentialsMessageHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
        {
            request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
            return base.SendAsync(request, cancellationToken);
        }
    }

and then in your Program.cs register it to DI

builder.Services.AddHttpClient("API", client => client.BaseAddress = new Uri("YOUR URL"))
            .AddHttpMessageHandler(s => new IncludeRequestCredentialsMessageHandler());

builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
                .CreateClient("API"));

Upvotes: 0

Related Questions