Minimal Api Attributes

PPoller8/28/2022
The testcode in my screenshot doesnt call the IAuthorizationFilter implementing attribute on my method head. when i use a inline delegate in programm.cs i loose DI(afaik).

i am sure there is a correct way, but for minimal apis i cant find it. Some tipps?

ps: in a controller api all works fina as expected.
Image
Ttebeco8/28/2022
what is [Authenticate] ?
Ttebeco8/28/2022
I know [Authorize] but not [Authenticate]
Ttebeco8/28/2022
add . after .MapGet() => .MapGet("....").
Ttebeco8/28/2022
and you'll see intelisens pop out
Ttebeco8/28/2022
there's likely something you want inside
Ttebeco8/28/2022
forget Authenticate / think Authorize
PPobiega8/28/2022
Also, minimal API doesn't support actionfilters. In .net 7 they support a new type of filter
Ttebeco8/28/2022
you only need endpoitn metadata for the quesiton
Ttebeco8/28/2022
you don't need ActionFilter
Ttebeco8/28/2022
and should avoid Filter 99% of the time in fact
Ttebeco8/28/2022
even in traditional MVC app
Ttebeco8/28/2022
here's AspNetCore 6 docs:
Ttebeco8/28/2022
here's a sample:
Ttebeco8/28/2022
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebRPauth.Data;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization(o => o.AddPolicy("AdminsOnly", 
                                  b => b.RequireClaim("admin", "true")));

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

var app = builder.Build();

app.UseAuthorization();

app.MapGet("/auth", [Authorize] () => "This endpoint requires authorization.");
app.MapGet("/", () => "This endpoint doesn't require authorization.");
app.MapGet("/Identity/Account/Login", () => "Sign in page at this endpoint.");

app.Run();
Ttebeco8/28/2022
zoom into relevant line:
Ttebeco8/28/2022
app.MapGet("/auth", [Authorize] () => "This endpoint requires authorization.");
Ttebeco8/28/2022
alternative:
app.MapGet("/auth", () => "This endpoint requires authorization")
   .RequireAuthorization();
Ttebeco8/28/2022
this RequireAuthorization will simply instanciate an AuthorizeAttribute IIRC
Ttebeco8/28/2022
and add it to the Metadata of that endpoint
Ttebeco8/28/2022
and that's how Authorization works
Ttebeco8/28/2022
there's many other sample in that link
PPoller8/28/2022
its a custom attribute. and i know we all should use MS Identity, but this is a test and i do not see it usefull all the time. but this is another topic
PPoller8/28/2022
so is IAuthorizationFilter the 1% or would you do stuff like this in middleware?
PPobiega8/28/2022
Authorize isnt a filter iirc, its actually a flag for the middleware to kick in
Ttebeco8/28/2022
there's 2 authorize
Ttebeco8/28/2022
that's the joke
Ttebeco8/28/2022
one is an action filter one is a simple attribute for metadata marking
Ttebeco8/28/2022
action filter gives access to what's after the model binder such as actual value inside the body
Ttebeco8/28/2022
the attribute will generally be used to run policy at middleware level which limits you to header
Ttebeco8/28/2022
(including jwt, all claims, url, ....)
Ttebeco8/28/2022
just not the request body content
Ttebeco8/28/2022
cc @Poller
Ttebeco8/28/2022
so it all comes down to what you need to run the authorization stuff
Ttebeco8/28/2022
what was the code of your authenticate thing @Poller ?
PPoller8/28/2022
gimme 20 minutes ill be right back
PPoller8/28/2022
it just cheks on controllers/routes:
- is a custom allowanonymous attribute set
- is the user attatched to the context and are a few user criteria met(locked, permissions(also attributes on routes))
PPoller8/28/2022
but as it seems, @Pobiega pointed out that it seems not working yet. so i wait till net7 to play around with this a bit more.
Ttebeco8/28/2022
allow anonymous or not is simple policy
Ttebeco8/28/2022
the sample i sent is about what it would look like if you check nothing beside "are you signed in"
Ttebeco8/28/2022
[Authorize] does that
Ttebeco8/28/2022
look at docs on on authorization for aspnetcore
Ttebeco8/28/2022
such as "docs aspnetcore claim based authorization"
Ttebeco8/28/2022
or "docs aspnetcore resource based authorization"
Ttebeco8/28/2022
these in google will likely send to great docs
Ttebeco8/28/2022
no you can still make that work
Ttebeco8/28/2022
minimal api did not broke anything that normal aspnetcore does
Ttebeco8/28/2022
it's 100% possible
Ttebeco8/28/2022
maybe not using an attribute
PPoller8/28/2022
dont get hung up on the authorize and best pacteces. this is just some tester project to play with stuff.

i might take a look into another approach without attributes. (thinking, for permissions i dont want to go without((
Ttebeco8/28/2022
100% you can do it since ... ever
Ttebeco8/28/2022
- is a custom allowanonymous attribute set
MMODiX8/28/2022
Ttebeco8/28/2022
¯\_(ツ)_/¯
Ttebeco8/28/2022
that's about it
Ttebeco8/28/2022
- is the user attatched to the context and are a few user criteria met(locked, permissions(also attributes on routes))
MMODiX8/28/2022
Ttebeco8/28/2022
this one literally show b.RequireClaim("admin", "true")));
Ttebeco8/28/2022
so a claim named admin on the user identity
Ttebeco8/28/2022
and check if it's value to true in a policy
Ttebeco8/28/2022
I would recommend you try the code before wondering if it will actually work or not
Ttebeco8/28/2022
and I would also google the thing I sent you
Ttebeco8/28/2022
especially the Resource Based one
MMODiX8/28/2022
Ttebeco8/28/2022
Image
Ttebeco8/28/2022
Image
Ttebeco8/28/2022
samples ... LOTS of samples
PPoller8/28/2022
resource based authorization looks interesting. its on my list for next weekend 🙂