Skip to content

Programmatically evaluating policies in ASP.NET Core

Programmatically evaluating policies in asp.net core

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.

programmatically evaluating policies in asp.net core demo

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:

Leave a Reply

Your email address will not be published.