In ASP.NET MVC, individual controller/actions can be protected by decorating the class/method with the System.Web.Mvc.Authorize attribute. The attribute provides for specifying a string that lists Users or Roles that are allowed to access the resource served by the class/method. There a several drawbacks in this design:
- The allowed users and roles are strings. Changing those values requires a re-compilation of the code.
- The authorization check occurs before the method is called. This means that resource-level checks (e.g. accessing a specific document) need to happen outside of the framework.
- The authorization code ends up in the same location as the application logic. There is a risk that changes to the authorization logic could affect the application logic.
In the upcoming version of ASP.NET Core MVC, the team has extended the authorization framework. While the list of users and roles is still supported, the implementation of the Authorize attribute has been re-worked to call AuthorizationHandlers that perform authorization checks based on AuthorizationRequirements. The Requirements express the data necessary for the Handler. The Attribute returns to the framework a result to indicate if the method should continue.
More information about the ASP.NET vNext is available at https://docs.asp.net/en/latest/security/authorization/claims.html
Back-Port Project
Since ASP.NET vNext is open source, we can see the planned implementation. Brock Allen suggested that their implementation could be back-ported to MVC 5. I agreed, and did just that. The project is at https://github.com/pschaeflein/mvc5-authorization-policy with a NuGet package published as https://www.nuget.org/packages/MVC5AuthZPolicy/.
The readme file on GitHub has examples of how to wire up the service and the samples have example Requirements/Handlers. In summary, there is an OWIN Middleware-compatible implementation as well as an example of using a base class to invoke the service. I plan to publish a few more samples that illustratate the following:
- Using Dependency Injection to inject the Authorizatoin Service into the pipeline
- Calling the Authorization service from the body of an Action method so that a specific resource can be part of the Authorization checks.
- A Requirement/Handler that uses an external call as part of the checks (database or service call).
I am happy for any feedback or contributions. I do not expect every developer to move to vNext the moment it releases, and I believe this framework will meet a need for most.