Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MapRazorComponents broken with FallbackPolicy RequireAuthenticatedUser #51836

Open
1 task done
davhdavh opened this issue Nov 3, 2023 · 9 comments
Open
1 task done
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer Docs This issue tracks updating documentation feature-blazor-server-auth Pillar: Complete Blazor Web

Comments

@davhdavh
Copy link
Contributor

davhdavh commented Nov 3, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

It seems fallback policy is broken for all blazor modes.

services.AddAuthorization(o => o.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
...
app.UseStaticFiles();
app.UseAuth...();
app.MapRazorComponents<App>()
   .AddInteractiveServerRenderMode();

results in a redirect to login when requesting /_framework/blazor.web.js.

services.AddAuthorization(o => o.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
...
app.UseStaticFiles();
app.MapRazorComponents<App>()
   .AddInteractiveServerRenderMode();
app.UseAuth...();

ALSO results in a redirect to login when requesting /_framework/blazor.web.js.

Expected Behavior

Putting Maps before UseAuth... => no auth check
Putting Maps after UseAuth... => auth check for pages, but not for staticfiles

Steps To Reproduce

See above

Exceptions (if any)

No

.NET Version

8.0.100-rc.2.23502.2

Anything else?

No response

@mkArtakMSFT mkArtakMSFT added this to the Planning: WebUI milestone Nov 6, 2023
@Tratcher Tratcher added area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer and removed area-security labels Nov 15, 2023
@ghost
Copy link

ghost commented Dec 29, 2023

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 6, 2024
@wtgodbe wtgodbe removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 6, 2024
@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 6, 2024
@codymullins
Copy link

Is there any kind of workaround here or timeline to a fix?

@bmarkovic17
Copy link

I've ended up putting @attribute {Authorize] which will use the default policy on all of my blazor components which by default is that a user needs to be authenticated, but can be adjusted if needed.

image

@wtgodbe wtgodbe removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 13, 2024
@halter73
Copy link
Member

dotnet/AspNetCore.Docs#31931 shows another example of someone else running into the same issue but for blazor.server.js which is a regression. Previously, it was much easier to just add the UseStaticFiles() before UseAuthorization() if you didn't want to require authentication for Blazor's static resources.

The workarounds I suggest could be used such as applying the [Authorize] attribute in the _Imports.razor file all have shortcomings. It makes me think that maybe we should add a simple boolean option to add [AllowAnonymous] to all of Blazor's static endpoints.

@codymullins
Copy link

codymullins commented Feb 29, 2024

@halter73 I ran into this - was getting 302 redirected on the _framework path. The solution you commented in the other issue is good as a workaround, but note that all the _framework paths will have the same issue.

I initially only checked for the specific path that was triggering the challenge but quickly discovered it needed to be a starts-with check.

image

I worked around it with a handler (have since disabled the "global auth" setting due to other issues, though.)

public class BlazorFrameworkAuthorizationMiddlewareResultHandler(ILogger<BlazorFrameworkAuthorizationMiddlewareResultHandler> log) : IAuthorizationMiddlewareResultHandler
{
    private readonly AuthorizationMiddlewareResultHandler handler = new();

    public async Task HandleAsync(
        RequestDelegate next,
        HttpContext context,
        AuthorizationPolicy policy,
        PolicyAuthorizationResult authorizeResult)
    {
        if (IsFrameworkPath(context.Request.Path) && authorizeResult.Challenged)
        {
            log.LogInformation("Bypassing challenge for _framework files");
            // allow required framework paths to be accessible anonymously
            await handler.HandleAsync(next, context, policy, PolicyAuthorizationResult.Success());
            return;
        }

        await handler.HandleAsync(next, context, policy, authorizeResult);
    }

    private bool IsFrameworkPath(string path)
    {
        return path.StartsWith("/_framework");
    }
}

@seanterry
Copy link

seanterry commented Jul 15, 2024

This is my workaround for a static SSR project:

AuthorizationPolicy defaultDeny = new AuthorizationPolicyBuilder()
    .RequireAssertion( context => context.Resource is HttpContext { Request : { Method: "GET", Path.Value: "/_framework/blazor.web.js" } } )
    .Build();

builder.Services.AddAuthorizationBuilder()
    .SetFallbackPolicy( defaultDeny )
    // other authz stuff
;

This seems to work well, and loudly reminds me when I have forgotten to explicitly set the authorization policy for an endpoint.

@gragundier
Copy link

What follows is yet another way to work around the problem. Defining the Fallback policy caused a lot of weird undesirable behavior, but we still wanted to protect our static files. I built what is essentially a wrapper for the StaticFilesMiddleware to ensure authentication before delivering the files.

public class CustomStaticFileMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, 
IOptions<StaticFileOptions> options, ILoggerFactory loggerFactory, IAuthorizationService authorizationService)
{
    private readonly RequestDelegate _next = next;

    private readonly StaticFileMiddleware _staticFileMiddleware = new(next, hostingEnv, options, loggerFactory);

    private readonly IAuthorizationService _authorizationService = authorizationService;

    public async Task Invoke(HttpContext context)
    {
        var result = await _authorizationService.AuthorizeAsync(context.User, null, new OurUserRequirement());
        if (result.Succeeded)
        {
            await _staticFileMiddleware.Invoke(context);
        }
        else
        {
            await _next(context);
        }
    }
}

The UseStaticFile() call is just a wrapper around a UseMiddleWare call to the StaticFileMiddleware so the replacement was luckily very simple.

            app.UseMiddleware<CustomStaticFileMiddleware>(Options.Create(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Static")),
                RequestPath = $"/static"
            }));

@boomalator
Copy link

I've ended up putting @attribute {Authorize] which will use the default policy on all of my blazor components which by default is that a user needs to be authenticated, but can be adjusted if needed.

image

This sounds like it works, but defeats the purpose of having a fallback policy. Sheesh.

Am i the only one who wants to protect all pages except a few?

@codymullins
Copy link

@boomalator no, you are certainly not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer Docs This issue tracks updating documentation feature-blazor-server-auth Pillar: Complete Blazor Web
Projects
None yet
Development

No branches or pull requests

10 participants