Page 64 - MSDN Magazine, October 2017
P. 64

User
Customer
Admin
Contents
Customer + Contents
put, a policy is an entity devised as a collection of requirements, which themselves are conditions that the current user must meet. The simplest policy is that the user is authenticated, while a com- mon requirement is that the user is associated with a given role. Another common requirement is for the user to have a particu- lar claim or a particular claim with a particular value. In the most general terms, a requirement is an assertion about the user iden- tity that attempts to access a method that holds true. You create a
policy object using the following code:
var policy = new AuthorizationPolicyBuilder() .AddAuthenticationSchemes("Cookie, Bearer") .RequireAuthenticatedUser() .RequireRole("Admin") .RequireClaim("editor", "contents") .RequireClaim("level", "senior")
.Build();
The builder object collects requirements using a variety of extension methods and then builds the policy instance. As you can see, requirements act on the authentication status and schemes, role, and any combination of claims read through the authentica- tion cookie or bearer token.
If none of the predefined extension methods for defining require- ments work for you, then you can always resort to defining a new requirement through your own assertion. Here’s how:
var policy = new AuthorizationPolicyBuilder() .AddAuthenticationSchemes("Cookie, Bearer") .RequireAuthenticatedUser() .RequireRole("Admin") .RequireAssertion(ctx =>
{
return ctx.User.HasClaim("editor", "contents") ||
ctx.User.HasClaim("level", "senior");
}) .Build();
The RequireAssertion method takes a lambda that receives the HttpContext object and returns a Boolean value. Therefore, the assertion is simply a conditional statement. Note that if you concat- enate RequireRole multiple times, then all roles must be honored by the user. If you want to express instead an OR condition, then you may resort to an assertion. In this example, in fact, the policy allows users that are either editor of contents or senior users.
Registering Policies
It’s not enough to define policies—you must also register them with the authorization middleware. You do this by adding the authori- zation middleware as a service in the ConfigureServices method of the startup class, like so:
services.AddAuthorization(options=> {
options.AddPolicy("ContentsEditor", policy => {
policy.AddAuthenticationSchemes("Cookie, Bearer"); policy.RequireAuthenticatedUser(); policy.RequireRole("Admin"); policy.RequireClaim("editor", "contents");
}); }
Each policy added to the middleware has a name, which is used to reference the policy within the Authorize attribute on the controller class:
[Authorize(Policy = "ContentsEditor")] public IActionResult Save(Article article) {
// ...
Figure 1 Hierarchy of Roles
operation, this filter runs before any of the other ASP.NET Core
filters. If the user isn’t authorized, the filter short-circuits the pipe- line and cancels the requests.
Custom authorization filters can be created, but most of the time you won’t need to do that. In fact, it’s preferable that you configure the existing authorization layer on which the default filter relies.
Roles, Permissions and Overrules
Roles are an easy way to group the users of an application based on what they can or cannot do. But they aren’t very expressive; at least, not enough to meet the needs of most modern appli- cations. For example, consider a relatively simple authorization architecture, serving regular users of the Web site and power users authorized to access the back office software and update content. A role-based authorization layer can be built around two roles— user and admin—defining which controllers and methods each group can access.
You run into problems when it comes to overrules—subtle distinctions that describe what users can or cannot do within a given role. For example, you may have users who enjoy access to back office systems. But of those users, some are authorized only to edit customer data, some only to work on content, and some to both edit customer data and work on content (see Figure 1).
In ASP.NET Core, the policy- based authorization framework is designed to decouple authorization and application logic.
Roles are essentially flat concepts. How would you flatten out even a simple hierarchy like the one shown in Figure 1? You could create four different roles—User, Admin, CustomerAdmin and ContentsAdmin—but as soon as the number of overrules grows, the number of required roles increases significantly. Even a simple exercise like this one shows that roles may not be the most effec- tive way to handle authorizations, except for simple scenarios and instances where backward compatibility is a priority. For everything else, there’s a different requirement. Enter policy-based authorization.
What’s a Policy, Anyway?
In ASP.NET Core, the policy-based authorization framework is designed to decouple authorization and application logic. Simply
}
60 msdn magazine
Cutting Edge


































































































   62   63   64   65   66