BitzArt / Blazor.Auth

Blazor authentication package
https://bitzart.github.io/Blazor.Auth/
MIT License
78 stars 10 forks source link

Blazor reverse proxy for accessing WebAPIs #11

Closed YuriyDurov closed 2 months ago

YuriyDurov commented 4 months ago
Hantse commented 4 months ago

Hello,

Probably link to this, it's possible to attach bearer in HTTP Client ? Custom handler ?

Kr,

YuriyDurov commented 4 months ago

@Hantse Hello

Currently (package version 0.*) you can access your user's bearer token as one of the claims provided in the user's AuthenticationState. In other words, if you inject the AuthenticationStateProvider somewhere in your app and then call it's GetAuthenticationStateAsync method, you should be able to get the user's bearer token from the AuthenticationState object it returns.

But we are planning on changing this in version 1.*. We are planning on removing the ability of client-side code to access the JwtPair in any way. The Jwt data should be stored as an HttpOnly (and, optionally, Secure) Cookie in the user's browser. This is necessary in order to counteract the potential for XSS vulnerabilities. This will be covered in more detail here: #6.

Blazor already provides some protection from cross-site scripting, but allowing the client part of your app unrestricted access to the user's JwtPair can still be dangerous.

This issue here is about allowing authorized http requests without accessing the JwtPair on the client device. The idea is that the Server part of your Blazor app should provide a configurable reverse proxy for accessing necessary WebAPIs. In other words, it should act as a configurable middleware between the user and an external WebAPI that the user needs to access. It should also be doing necessary manipulations on the users' requests, like appending bearer tokens to the outbound part of the request.

I suggest you to keep an eye on upcoming updates, especially regarding changes between 0.* and 1.*, as this migration will likely require some adjustments to your solution's code.

We are doing this to ensure the extra safety of your users' data.

Hope this brings some additional clarity on this aspect of the package.

Hantse commented 4 months ago

Hello !

Thx for feedback !

I've do that's as "workaround" :

 public class ApplicationAuthorizationMessageHandler(ICookieService cookieService)
     : DelegatingHandler
 {
     protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
     {
         var token = await cookieService.GetAsync("AccessToken");
         if (token != null)
         {
             request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token.Value}");
         }

         return await base.SendAsync(request, cancellationToken);
     }
 }

But it's possible better :

app.MapForwarder("/weather-forecast", "https://weatherapi", transformBuilder =>
{
    transformBuilder.AddRequestTransform(async transformContext =>
    {
        var accessToken = await transformContext.HttpContext.GetTokenAsync("access_token");
        transformContext.ProxyRequest.Headers.Authorization = new("Bearer", accessToken);
    });
}).RequireAuthorization();