Here is an example controller to explain the case
[Authorize]
public class AccountController : ControllerBase
{
[AllowAnonymous]
[Authorize(Policy = "SpecificPolicy")]
public string MethodA() {}
public string MethodB() {}
}
The issue I'm having is that if I remove the AllowAnonymous attribute then Authorize on the controller takes precedence which I don't want for MethodA.
When I keep AllowAnonymous for MethodA then Authorize(Policy = "SpecificPolicy") is ignored.
When I keep AllowAnonymous for MethodA then Authorize(Policy = "SpecificPolicy") is ignored.
[AllowAnonymous]
bypasses all other authorization attributes. When you have it with other authorize attributes at the same time, all other attributes are ignored, even other attributes are the-more-specific method level.
For example:
[AllowAnonymous]
public class DashboardController : Controller
{
[Authorize]
public IActionResult Index()
{
return View();
}
}
/dashboard
will be open/public.
The issue I'm having is that if I remove the AllowAnonymous attribute then Authorize on the controller takes precedence which I don't want for MethodA.
When you have multiple authorize attributes, all of them need to be satisfied before you can make the call to the method. In your case, both [Authorize]
and [Authorize(Policy = "SpecificPolicy")]
must pass before access is granted.
If you don't want [Authorize]
to take the precedence, you can only apply it to method B:
public class AccountController : ControllerBase
{
[Authorize(Policy = "SpecificPolicy")]
public string MethodA() {}
[Authorize]
public string MethodB() {}
}
I want to avoid putting specific [Authorize] attributes on actions since that Controller has lots of actions but a single action that has it's own authorize rule.
Then this might be good time for you to separate MethodA into Areas.
For example:
You still have [Authorize]
on your AccountController
, but just take out the MethodA:
[Authorize]
public class AccountController : ControllerBase
{
public string MethodB() {}
}
Then you create an Area for MethodA:
[Area("specific")]
[Authorize(Policy = "SpecificPolicy")]
public abstract class SpecificControllerBase : ControllerBase
{ }
public class AccountController : SpecificationControllerBase
{
public string MethodA() {}
}
Lastly you need to register the area route in your Startup.cs
:
app.UseMvc(routes =>
{
...
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller=dashboard}/{action=index}/{id?}");
routes.MapRoute(
name: "default",
template: "{controller=home}/{action=index}/{id?}");
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With