In ASP.Net Core 3.0 Preview 7, I tried to write some code as follows:
public void Configure(IApplicationBuilder app) {
app.MapWhen(context =>
context.Request.Path.StartsWithSegments(
new PathString("/UnsecureLog")),
a => {
a.UseRouting();
a.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}
);
app.UseAuthentication();
app.UseAuthorization();
app.MapWhen(context =>
context.Request.Path.StartsWithSegments(
new PathString("/SecureLog")),
a => {
a.UseRouting();
a.UseEndpoints(endpoints => {
endpoints.MapControllers()
.RequireAuthorization("MustBeReader");
});
}
);
}
My goal was to allow certain controllers to be handled in the middleware without authentication, and my thinking was that MapWhen() was the way to pull that off.
Instead I see this error when hitting the /UnsecureLog
endpoint:
System.InvalidOperationException: Endpoint ... contains authorization metadata,
but a middleware was not found that supports authorization.
Configure your application startup by adding app.UseAuthorization()
inside the call to Configure(..) in the application startup code.
Translation: "How's about you go and implement security features for that endpoint you didn't want to secure".
My takeaway is that any call to RequireAuthorization("MustBeReader")
in any MapWhen() block handling controller logic will in fact be be applied to all MVC controller routes.
My current workaround is to remove the .RequireAuthorization("MustBeReader")
call in the 2nd MapWhen() code block and re-apply it as an attribute ([RequireAuthorization("MustBeReader")]
) to those endpoints I wish to secure. This works with no errors and produces the desired behavior.
But that sorta wasn't the goal, was it?
I'd prefer to manage whole groups of controllers with similar policies, while sparing others from security at all, and handle all of this from within Configure(). Instead I must apply the desired authorization requirements to each and every controller, piecemeal.
I am hoping there is a better way to implement routing that avoids the issue noted here. Maybe I'm doing something improperly.
Thoughts, anyone?
Move the below code higher up in your Startup class (above app.MapWhen
).
app.UseAuthentication();
app.UseAuthorization();