Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to apply Authorize attribute on individual Razor Page handlers #8737

Closed
omfgicbf opened this issue Mar 22, 2019 · 16 comments
Closed

Unable to apply Authorize attribute on individual Razor Page handlers #8737

omfgicbf opened this issue Mar 22, 2019 · 16 comments
Milestone

Comments

@omfgicbf
Copy link

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:

  1. Migrate an MVC view and associated controller methods to a single Razor Page.
  2. Attempt to apply a [Authorize] attribute on a handler method such as OnGet or OnPost (or other named handler).
  3. 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

dotnet/AspNetCore.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.

@blowdart blowdart added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Mar 22, 2019
@mkArtakMSFT
Copy link
Member

Thanks for contacting us, @omfgicbf.
You're right, this is the current state of the system. While this is not something we plan to address right away, we'll move this ask to the backlog to review it at a later time.

@mkArtakMSFT mkArtakMSFT added enhancement This issue represents an ask for new feature or an enhancement to an existing one PRI: 2 - Preferred labels Mar 23, 2019
@mkArtakMSFT mkArtakMSFT added this to the Backlog milestone Mar 23, 2019
@omfgicbf
Copy link
Author

Thanks for getting back to me @mkArtakMSFT.

Is the absence of support for AuthorizeAttribute just a matter of priority? or is controlling authorization at the handler level, not the recommended way of doing things in Razor Pages?

It would help with making some design decisions, i.e. do I roll my own per-handler attribute and wait for the proper implementation (possibly) in the future, or should I be doing something completely different (and more correct?) now?

I don't mind (p)re-inventing the wheel, but only if it's in line with the recommended design (as it is, for example, with MVC).

@natelaff
Copy link

natelaff commented Apr 1, 2019

I'm curious as to what the recommended approach is as well. I have a Razor Page, Get is anonymous, Post requires authorization. (i.e. posting a blog comment).

@Zenexer
Copy link
Contributor

Zenexer commented Jun 22, 2019

@mkArtakMSFT, is there a recommended alternative pattern we should be using?

@mkArtakMSFT
Copy link
Member

@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?

@Zenexer
Copy link
Contributor

Zenexer commented Jun 24, 2019

Thanks for the response, @mkArtakMSFT; that helps significantly with planning.

@ghost
Copy link

ghost commented Sep 30, 2019

We are running into the same issue for our .NET Core application. This seems like going backward in functionality from ASP.NET MVC where you could authorize GET and POST actions on a page separately. However, it is what it is.

IAsyncPageFilter/OnPageHandlerSelected method reeks of asking for anguish going forward.

Our solution involved creating API controllers to handle the POST requests submitted as the result of forms on the page which require separate authorization permissions from the GET request of loading the page.

In our case, we are using JavaScript and passing JSON back down from these API controllers and reloading the page if our server(s) tell us the updates asked for in the POST request were both authorized and succeeded. While I do not prefer to manage actions relevant to a single page on both a razor page and one or sometimes several different API controllers, especially simple form pages where JavaScript would otherwise be unnecessary, I would prefer the alternatives even less.

@josephsmi2013
Copy link

Wow! I'm really surprised to see such a huge regression in Razor pages from MVC. Some attention on this quick seems like a "no-brainer"?!?!

@tyddynonn
Copy link

I'm just tackling a migration from ASP.Net 5 to Core 3, was planning to use Razor Pages but this is a deal-breaker for me. I'm really not going to refactor most of my Controllers to work around this limitation.

Back to MVC it is.

@phcd30
Copy link

phcd30 commented Jan 11, 2020

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.

@Franklin89
Copy link

As a "work around" it is always possible to inject an IAuthorizationService into 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.

@danobri
Copy link
Contributor

danobri commented Apr 8, 2020

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.

@pranavkm
Copy link
Contributor

pranavkm commented Apr 9, 2020

Thank you for all your feedback. We appreciate that this is a particularly problematic pain point with Razor Pages. Unfortunately adding support for this feature would require fundamental changes to how Razor Pages works under the hoods[1], as well as breaking API changes[2]. This needs a fairly detailed design and discussion before we can proceed, which we are unable to commit to for the upcoming release.

At this time, we have two workarounds that you could consider using instead:

a) You could consider using separate pages and using partials to share the view content. AuthorizeAttribute could be applied on a per-page basis.
b) If you must use a single page but require auth on individual handlers, you could write a filter that performs authorization as part of IAsyncPageFilter.OnPageHandlerSelectionAsync. Here's the relevant pieces:

Note that the filter in this sample does not compose with auth attributes applied either to the page, page model, or globally and will result in authentication and authorization executing multiple times if you have AuthorizeAttributes or AuthorizeFilters independently applied to the page.


[1] - An action descriptor describes the unit of routing \ authorization \ execution in MVC. PageActionDescriptor used to describe a Razor Page does not include a specific handler. Compare this to ControllerActionDescriptor used by controller actions that specifies the exact method to execute.

[2] - With endpoint routing, authorization executes as part of a middleware that executes before routing gets to MVC. IAuthorizeFilter executes before IPageFilter \ IAsyncPageFilter. Page filters allows you to change the handler that is to be executed. This API is hard to reconcile with the auth requirements of the handler. Supporting auth on the handlers would require us to remove this API.

@Coscotex101
Copy link

Hi, just reminding everyone that comes across this, that it's been over a year that this was posted and we are still waiting for this feature to be returned, especially since there are lots of devs clamoring for it. Well me and my team will keep on using Core 2.1 where this function works fine until the "SMALL TEAM" gets around this. @mkArtakMSFT @pranavkm @Rick-Anderson

@Rick-Anderson
Copy link
Contributor

Authorize attribute and Razor Pages has been published which has our recommendations and current plans.

Back to MVC it is.

Why not use MVC controllers where you need mixed auth and RP where you don't? It's not all or none. PR dotnet/AspNetCore.Docs#18879 makes that suggestion.

@pranavkm pranavkm modified the milestones: Backlog, Discussions Oct 14, 2020
@pranavkm pranavkm removed enhancement This issue represents an ask for new feature or an enhancement to an existing one area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels Oct 14, 2020
@ghost
Copy link

ghost commented Dec 13, 2020

Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.

This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue!

@ghost ghost closed this as completed Dec 13, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Jan 12, 2021
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests