aspnetcore
aspnetcore copied to clipboard
FallbackPolicy takes precedence over AuthorizeFilters added using Conventions
Is there an existing issue for this?
- [X] I have searched the existing issues
Describe the bug
Security policies applied using the MvcOptions.Conventions does not apply if a FallbackPolicy is specified
I want to add a security policy for a controller using MvcOptions.Conventions, if no FallbackPolicy is specified the security policies are evaluated as expected. However if a FallbackPolicy is specified, only that applies.
Expected Behavior
I would expect the AuthorizeFilters added using Conventions to take precedence over the FallbackPolicy
Steps To Reproduce
The following code should be sufficient to reproduce the problem
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Authorization;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
options.Conventions.Add(new AllowAnonymousConvention());
});
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("allowAnonymous", new AuthorizationPolicyBuilder()
.RequireAssertion(_ => true)
.Build());
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAssertion(_ => false)
.Build();
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
[ApiController]
[Route("[controller]")]
public class HelloWorldController : ControllerBase
{
[HttpGet]
public string Get()
{
return "Hello world";
}
}
public class AllowAnonymousConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
if (controller.ControllerType.Equals(typeof(HelloWorldController)))
{
controller.Filters.Add(new AuthorizeFilter(new IAuthorizeData[]
{
new AuthorizeAttribute("allowAnonymous")
}));
}
}
}
Exceptions (if any)
No response
.NET Version
6.0.101
Anything else?
No response
@HaoK i believe this is expected right? You shouldn't mix policies and filters
It's weirder - the AuthZ middleware will evaluate the fallback policy since it does not see the filter, and MVC will then execute the filter. Applying the attribute directly to the controller would be the easiest way to do this. You might also be able to add the AttributeAttribute
to SelectorModel.EndpointMetadata
but I haven't really tried it out to see if it works.
Yeah this isn't really something we designed for, its more like a gap
Yes, using the SelectorModel.EndpointMetadata
does the trick
public class AllowAnonymousConvention : IActionModelConvention
{
public void Apply(ActionModel action)
{
if (action.Controller.ControllerType.Equals(typeof(HelloWorldController)))
{
foreach (var s in action.Selectors)
{
s.EndpointMetadata.Add(new AuthorizeAttribute("allowAnonymous"));
}
}
}
}
I would however argue that this behaviour is counter intuitive
Triage: Fallback policies take precedence over auth filters and should not be used together. Worth documenting.
Thanks for contacting us.
We're moving this issue to the .NET 7 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.
Thanks for contacting us.
We're moving this issue to the .NET 8 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.
Fixed via updated docs