Skip to content

How to add authentication header to HTTP requests created by BrowserHttpSink? #7

Description

@szmalec

I would like logs generated for an authenticated user to be sent to the server along with the user's token in the headers.
If the user signs off, log entries should be sent to the server without this token.

Scenario:
I am using Serilog.Sinks.BrowserHttp in my Blazor WASM app:

Log.Logger = new LoggerConfiguration()
    .WriteTo.BrowserHttp()
    .CreateLogger();

try {
    Log.Information("Starting app ({clientAppVersion})...", typeof(Program).Assembly.GetName().Version);
    // https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-preview-1-release-now-available/
    var builder = WebAssemblyHostBuilder.CreateDefault(args);
    builder.Services.AddSingleton<MyCustomJwtAuthService>();
    //...
    builder.RootComponents.Add<App>("app");
    await builder.Build().RunAsync();
}
catch (Exception ex)
{
    Log.Fatal(ex, "An exception occurred while creating the WASM host");
    throw;
}

My app uses some king MyCustomJwtAuthService (which is also used in my custom AuthenticationStateProvider implementation) which holds JWT token for currently signed in user (it also silently refreshes token). This JWT token is added to headers (_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);) - so when HttpClient is used then HTTP requests are authenticated.
As I can see in sources Blazor registers in DI singleton for HttpClient, but BrowserHttpSink creates its own HttpClient instance and Authorization header added by MyCustomJwtAuthService does not affect HttpClient instance created in BrowserHttpSink - so I can not extract authenticated user data from requests perfomed by BrowserHttpSink...
I know that BrowserHttpSink accepts HttpMessageHandler as parameter but there are probably some issues related to used in Blazor WasmHttpMessageHandler (eg. see how folks are creating instances here).
Maybe it would be better for BrowserHttpSink to take a parameter of type Func<HttpClient> - so that I could somehow decide whether to provide an instance created by DI or maybe a temporary instance before the DI system produces the correct instance for me?
Although this may also not be ideal, because logs are sent to the server with a delay, so logs generated for an authenticated user can be sent after logging out ...

Any suggestions?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions