aspnetcore: Unable to apply Authorize attribute on individual Razor Page handlers
Describe the bug
In MVC, I’m able to place an AuthorizeAttribute on individual methods, however, when porting to Razor Pages, the AuthorizeAttribute can only be applied at the page level.
To Reproduce
Steps to reproduce the behavior:
- Migrate an MVC view and associated controller methods to a single Razor Page.
- Attempt to apply a
[Authorize]attribute on a handler method such asOnGetorOnPost(or other named handler). - Receive build warning
Warning MVC1001 'AuthorizeAttribute' cannot be applied to Razor Page handler methods. It may be applied either to the Razor Page model or applied globally.
Expected behavior
The ability to use the AuthorizeAttribute, and corresponding Policy/Claim/Role based authorization at the handler level; not just for all handlers at the page level.
Additional context
aspnet/Docs#6301 seems to acknowledge this, but it doesn’t appear to have been addressed.
aspnet/Mvc#7842 notes that it’s a common question, but the outcome was a plan to warn people that putting AuthorizeAttribute on handler methods doesn’t work (i.e. aspnet/Mvc#7684), but doesn’t offer a solution to the use-case.
The documentation on Razor Pages here discusses support for different handlers in a page; how would one authorize individual actions based on a policy/claim/role?
I’ve seen suggestions that a custom IAsyncPageFilter, or indeed overriding OnPageHandlerSelected can be used, but these smell of workaround, and from a structural point of view, they decouple the authorization from the method which is less than ideal (and something which policy based authorization seems to have been implemented to avoid).
Is IAsyncPageFilter/OnPageHandlerSelected the best-practice solution to this? or have I got the use-case wrong and the concept of authorizing at handler level in Razor Pages is just the wrong way of looking at things? (e.g. should I just have one page per policy?)
Apologies in advance if this is a simple question and I’m missing something, however, my Googlefoo is not strong on this one, and I cannot seem to find a straight answer anywhere.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 17
- Comments: 16 (8 by maintainers)
Adding a polite WTF to this. Any update on when this will be fixed? Using a small team as a reason doesn’t really work for a company the size of Microsoft.
I agree with others - this does not feel like a backlog item, but something that should be given priority. I just spent a bunch of time creating custom authorization attributes only to discover I can’t apply them to the Razor page methods I designed them for. I’ll inject IAuthorizationService as a workaround, but really think this should be prioritized.
I don’t see any reason this feature makes more sense for MVC than for Razor Pages. The ability to create multiple handlers for a single HTTP verb is a really useful feature of Razor Pages. I would think a common use case is to have multiple POST handlers for different groups of users. But if the handlers can’t be authorized separately, it negates the utility of having multiple handlers in a single Razor Page. If there is a justification for not making this a priority other than “we have a lot to do” I would be interested in hearing what it is.
As a “work around” it is always possible to inject an
IAuthorizationServiceinto the PageModel and then do the authorization “manually”. Of course this has other impacts, such as the time when authorization is happening in the pipeline. But it is a work around until this issue is tackled by the team.@omfgicbf, we’re pretty small team and we choose very carefully on what we focus our efforts on. At the moment, this is not something we plan to change. As for why it’s the case, that’s because in MVC a Razor Page is treated as single unit from authorization perspective. You should definitely not block yourself on this and wait for us to handle it soon. That may not happen soon. As for what will be the recommended approach, @pranavkm do you have some guidance here?