Programmatically evaluating policies is useful when we want to provide access or hide some data based on the user’s access to a policy.
In our previous posts, we’ve seen how we can create policy-based authorization and how to set up multiple authorizations in asp.net core.
In this post, we’ll see how to programmatically evaluate a policy in
- Razor Pages
- Controllers/API controllers
IAuthorizationService to evaluate policies
We have IAuthorizationService
in ASP.NET Core which has methods that check policy-based permissions for a user.
The IAuthorizationService
has several AuthorizeAsync
methods all of them take the ClaimsPrincipal
as a parameter.
Methods in the interface:
Task<AuthorizationResult> AuthorizeAsync(ClaimsPrincipal user, object? resource, IEnumerable<IAuthorizationRequirement> requirements); Task<AuthorizationResult> AuthorizeAsync(ClaimsPrincipal user, object? resource, string policyName);
Extension methods on IAuthorizationService
:
Task<AuthorizationResult> AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, object? resource, IAuthorizationRequirement requirement); Task<AuthorizationResult> AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, object? resource, AuthorizationPolicy policy) Task<AuthorizationResult> AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, AuthorizationPolicy policy) Task<AuthorizationResult> AuthorizeAsync(this IAuthorizationService service, ClaimsPrincipal user, string policyName)
All the methods return AuthorizationResult
. The AuthorizationResult
class has Succeeded and Failure properties which can be checked to determine the outcome.
Programmatically evaluating policy in razor pages
We will use the AuthorizeAsync
method in the IAuthorizationService
to validate our policies.
Remember for our policy-based authorization post we included links to our premium and standard lounges only when the user is signed in.
@if (SignInManager.IsSignedIn(User)) { <li class="nav-item"> <a class="nav-link text-dark special-link" asp-area="" asp-page="/PremiumLounge" style="background: yellow;">Premium Lounge</a> </li> <li class="nav-item"> <a class="nav-link text-dark special-link-2" asp-area="" asp-page="/StandardLounge" >Standard Lounge</a> </li> }
Now, let’s just get things tighter by showing the links to the users who have access to premium or standard lounge pages.
We have two separate policies already for Premium and Standard lounges. Let’s use them here.
First, we inject the IAuthorizationService
into the razor page.
@using Microsoft.AspNetCore.Authorization @inject IAuthorizationService AuthorizationService
And in the Layout.cshtml
file we have this code
@if (SignInManager.IsSignedIn(User)) { var isPremium = await AuthorizationService.AuthorizeAsync(User, "PremiumOnly"); var isStandard = await AuthorizationService.AuthorizeAsync(User, "StandardOnly"); if (@isPremium.Succeeded) { <li class="nav-item"> <a class="nav-link text-dark special-link" asp-area="" asp-page="/PremiumLounge" style="background: yellow;">Premium Lounge</a> </li> } if (@isStandard.Succeeded) { <li class="nav-item"> <a class="nav-link text-dark special-link-2" asp-area="" asp-page="/StandardLounge">Standard Lounge</a> </li> } }
We check for our policy names here and if they are successful only then we will show the links on the page.
Here is what a standard user’s view looks like.
A standard user can now only see the Standard Lounge link.
Programmatically evaluating policy in action methods
After that razor page demo, you should’ve guessed by now, we inject IAuthorizationService
in the controller and call the AuthorizeAsync
method and check the succeeded property on the result.
Here is our new user access controller.
[Route("api/[controller]")] [ApiController] public class UserAccessController : ControllerBase { private readonly IAuthorizationService _authorizationService; public UserAccessController(IAuthorizationService authorizationService) { _authorizationService = authorizationService; } [HttpGet] public async Task<ActionResult<(bool isPremium, bool isStandard)>> GetUserPermissionsAsync() { var isPremium = await _authorizationService.AuthorizeAsync(User, "PremiumOnly"); var isStandard = await _authorizationService.AuthorizeAsync(User, "StandardOnly"); return Ok(new Tuple<bool, bool>(isPremium.Succeeded, isStandard.Succeeded)); } }
Notice that we’ve to pass in the claims user to access the AuthorizeAsync
method.
Here is the result for a standard user trying to invoke the API.
{"item1":false,"item2":true}
References:
Karthik is a passionate Full Stack developer working primarily on .NET Core, microservices, distributed systems, VUE and JavaScript. He also loves NBA basketball so you might find some NBA examples in his posts and he owns this blog.