17

I'm looking for a variant of this

@if (SignInManager.IsSignedIn(User) && User.IsInRole(Roles.Administrator))
{
    <div id="editArticle">

but instead of checking after the role I'm after a check into the policy much like you would in a controller by doing this.

[Authorize(Policy = Policies.RequireAdmin)]
Thomas Andreè Wang
  • 3,142
  • 4
  • 31
  • 50

6 Answers6

23

This seems similar to question asked here

I found this link which may be helpful: https://docs.asp.net/en/latest/security/authorization/views.html

Examples from that page:

@if (await AuthorizationService.AuthorizeAsync(User, "PolicyName"))
{
    <p>This paragraph is displayed because you fulfilled PolicyName.</p>
}

In some cases the resource will be your view model, and you can call AuthorizeAsync in exactly the same way as you would check during resource based authorization;

@if (await AuthorizationService.AuthorizeAsync(User, Model, Operations.Edit))
{
    <p><a class="btn btn-default" role="button"
    href="@Url.Action("Edit", "Document", new {id= Model.Id})">Edit</a></p>
}
Community
  • 1
  • 1
James P
  • 2,003
  • 2
  • 17
  • 27
20

With Dot net core 2.0 AuthorizationService.AuthorizeAsync no longer returns a boolean, it returns a AuthorizationResult. A working version for dot net core 2.0 will be something like this:

@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService

@if ((await AuthorizationService.AuthorizeAsync(User, "RequireAuthenticatedUser")).Succeeded)
{
     <li><a asp-area="" asp-controller="Roles" asp-action="Index">Roles</a></li>
}
Talnaci Sergiu Vlad
  • 692
  • 1
  • 8
  • 16
5

Therefore the complete view contains:

@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService

// Your HTML elements and i.e.:
@if (await AuthorizationService.AuthorizeAsync(User, "RequireAuthenticatedUser"))
{
     <li><a asp-area="" asp-controller="Roles" asp-action="Index">Roles</a></li>
}
Jesus Mostajo
  • 51
  • 1
  • 2
1

If you're going to use this in many views, then you'd better implement a custom RazorPage:

public abstract class MyRazorPage<T> : RazorPage<T>
{
    public async Task<bool> HasPolicyAsync(string policyName)
    {
        var authorizationService = Context.RequestServices.GetService(typeof(IAuthorizationService)) as IAuthorizationService;
        bool isAdmin = (await authorizationService.AuthorizeAsync(User, policyName)).Succeeded;
        return isAdmin;
    }
}

then open _ViewImports.cshtml and add the next instruction:

@inherits MyRazorPage<TModel>

now you can call HasPolicyAsync() method from any view:

    if (await HasPolicyAsync(Policies.RequireAdmin))
    {
        <h2>Admin is authorized</h2>
    }

It would look much more concise.

Sergey
  • 4,403
  • 3
  • 28
  • 40
1

Its best handled with TagHelpers in most scenarios now. You can use it like:

<li policy="@MyGroups.Administrators">
....

So no longer Magicstrings :-)

See: https://www.davepaquette.com/archive/2017/11/05/authorize-tag-helper.aspx

0

To put it even more succinctly:

@inject Microsoft.AspNetCore.Authorization.IAuthorizationService authorizationService

@if (await authorizationService.AuthorizeAsync(User, null, "RequireAuthenticatedUser"))
{
     <li><a asp-area="" asp-controller="Roles" asp-action="Index">Roles</a></li>
}

It appears AuthorizeAsync() requires the resource parameter, but null can be passed as in my example.

Darren
  • 4,008
  • 3
  • 35
  • 52