How to set authorization policy in C# middleware `app.Map` IApplicationBuilder

106 Views Asked by At

I have an authorization policy that works in this simple middleware: app.Map("/test", () => "hi").RequireAuthorization("WebAPI");

Now I want the same as above but this time use IApplicationBuilder, I am wondering how can I do the same in app.Map("/proxy", Handle)

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
    builder.Services.AddAuthentication()
        .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

    builder.Services.AddAuthorization(options =>
    {
        options.AddPolicy("WebAPI", new AuthorizationPolicyBuilder(OpenIdConnectDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme)
            .RequireAuthenticatedUser()
            .Build());
        options.FallbackPolicy = new AuthorizationPolicyBuilder(OpenIdConnectDefaults.AuthenticationScheme)
            .RequireAuthenticatedUser()
            .Build();
        
        options.DefaultPolicy = options.GetPolicy("WebAPI")!;
    });
    
    builder.Services.AddControllers();

    builder.Services.AddHttpForwarder();

    var app = builder.Build();

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();
    
    app.UseAuthentication();
    app.UseAuthorization();

    app.Map("/test", () => "hi").RequireAuthorization("WebAPI");  // auth works in this
    app.Map("/proxy", Handle); // auth doesn't work in this

    app.MapControllers();

    app.Run();
}

private static void Handle(IApplicationBuilder app)
{
    app.Run(async httpContext =>
    {
        if (httpContext.User.Identity is { IsAuthenticated: false })
        {
            httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            await httpContext.Response.WriteAsync("Unauthorized");
            return;
        }
        
        httpContext.Response.StatusCode = 200;
        await httpContext.Response.WriteAsync("Hello");
    });
}
1

There are 1 best solutions below

0
On

You need to Inject AuthorizationService or get Service Instance in Handle Method and check for StatusCode(we can find weather user is autorized or not).

private static void Handle(IApplicationBuilder app)
    {
        app.Run(async httpContext =>
        {
            var authorizationResult = await app.ApplicationServices.GetRequiredService<IAuthorizationService>().AuthorizeAsync(httpContext.User, "WebAPI");
            if (!authorizationResult.Succeeded)
            {
                httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                await httpContext.Response.WriteAsync("Unauthorized");
                return;
            }

            httpContext.Response.StatusCode = 200;
            await httpContext.Response.WriteAsync("Hello");
        });
    }