josibu
josibu

Reputation: 672

ASP.Net MVC Custom Authorization Policy Provider in razor view

For some application I need a custom Authorization Policy provider and followed this link and was able to successfully create one that works in the controller. Now when it comes to the view, in role-based authorization you can simply use the term @if (User.IsInRole("SomeRole")) to display or hide divs and resources.

How can I use a custom Authorization Policy provider in the view to determine if a given user could see stuff based on the evaluation of the policy?

I searched the web and couldn't find helpful information about it and also tried playing round with

@if ((await AuthorizationService.AuthorizeAsync(User, "PolicyName")).Succeeded)

But this wasn't successful either - it's not a policy either.

Has anyone done this before?

Update

I am using the custom policy provider in the controller as follows:

[MinimumAgeAuthorize(15)]
public IActionResult Index()
{
       //some code
}

I cannot do

@if ((await AuthorizationService.AuthorizeAsync(User, "MinimumAgeAuthorize(15)")).Succeeded)

What is the equivalent for it in the razor view?

Upvotes: 2

Views: 2196

Answers (1)

user4864425
user4864425

Reputation:

I don't know what didn't work for you, but this is how you can use the AuthorizationService.

For this example let's assume that you defined a policy in startup:

services.AddAuthorization(options =>
{
    // assume that claimtype of role is role.
    options.AddPolicy("MyRolePolicy", policy => policy.RequireClaim("role", "SomeRole"));
});

This means that code restricted with 'MyRolePolicy' is only accessable when the user has the role 'SomeRole'. The equivalent of User.IsInRole("SomeRole").

In the view inject the service and test the policy for the user:

@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService _authorizationService

@if ((await _authorizationService.AuthorizeAsync(User, "MyRolePolicy")).Succeeded)
{
}

When you use Custom Authorization Policy Providers, the policies are added through middleware, e.g.:

public class AuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider
{
    public AuthorizationPolicyProvider(IOptions<AuthorizationOptions> options) : base(options)
    {
    }

    public async override Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {
        // check static policies first
        var policy = await base.GetPolicyAsync(policyName);

        if (policy == null)
            return new AuthorizationPolicyBuilder().AddRequirements(new PermissionRequirement(policyName)).Build();

        return policy;
    }
}

In this example the policies are added (if not exists) as permission where claimtype is permission and value is policyname. When I add the policy MyPermission it will check for a claimtype permission with value MyPermission.

In the view:

@if ((await _authorizationService.AuthorizeAsync(User, "MyPermission")).Succeeded)
{
}

I'm not sure what you mean by 'it's not a policy either', but the Authorization Policy Provider returns policies. So you should be able to validate these policies. Whether it's a simple claimtype (e.g. permission or role) or a more complex policiy with parameters. But the name must match. Also make sure that you inject the necessary handlers, services, etc.

Update

You can also validate using requirements:

@if ((await _authorizationService.AuthorizeAsync(User, null, new MinimumAgeRequirement(15))).Succeeded)

Where MinimumAgeRequirement is the requirement itself.

As documented:

AuthorizeAsync(ClaimsPrincipal, Object, IEnumerable<IAuthorizationRequirement>)

Checks if a user meets a specific set of requirements for the specified resource

Upvotes: 7

Related Questions