We will discuss how to perform authorization checks in views in asp.net core mvc. This technique is very useful, if you want to show or hide UI elements based on whether the logged-in user has access to them or not.
Role based authorization check in views in asp.net core mvc
Show Manage navigation menu item only if the user is signedin and member of the Admin role.
Navigation menu is in the layout view. To check if the user is signedin, inject ASP.NET Core SignInManager service
Claims based authorization check in views in asp.net core mvc
On the ListRoles view, we want to display Edit button ONLY if the signed-in user has satisfied EditRolePolicy.
To satisfy EditRolePolicy, the logged-in user must have Edit Role claim. We discussed claim policies and claims based authorization in detail in Part 94 of ASP.NET Core tutorial.
To check if the signed-in user satisfies EditRolePolicy, inject IAuthorizationService service into the view
Pass the user and the name of the policy as parameters to AuthorizeAsync() method of IAuthorizationService. Succeeded property returns true if the policy is satisfied, otherwise false.
Authorization checks in views alone is not enough
It's not enough if we just show or hide UI elements on the view. The respective controller actions must also be protected. Otherwise, the user can directly type the URL in the address bar and access the resources.
In our example, though Edit button is hidden, the user can directly type the following URL to get to the EditRole action
Make sure to protect the respective controller action as well
Service injection in multiple views
If you need IAuthorizationService in multiple views, consider importing in _ViewImports.cshtml, so you do not have to import it in every individual view.
Role based authorization check in views in asp.net core mvc
Show Manage navigation menu item only if the user is signedin and member of the Admin role.
Navigation menu is in the layout view. To check if the user is signedin, inject ASP.NET Core SignInManager service
@using Microsoft.AspNetCore.Identity
@inject SignInManager<ApplicationUser> SignInManager
@inject SignInManager<ApplicationUser> SignInManager
- SignInManager service IsSignedIn(User) method returns true if the user is signed in otherwise false.
- To check if the User is a member of the given role, use IsInRole() method
@if (SignInManager.IsSignedIn(User) && User.IsInRole("Admin"))
{
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Manage
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item"
asp-controller="Administration" asp-action="ListUsers">
Users
</a>
<a class="dropdown-item"
asp-controller="Administration" asp-action="ListRoles">
Roles
</a>
</div>
</li>
}
Claims based authorization check in views in asp.net core mvc
On the ListRoles view, we want to display Edit button ONLY if the signed-in user has satisfied EditRolePolicy.
To satisfy EditRolePolicy, the logged-in user must have Edit Role claim. We discussed claim policies and claims based authorization in detail in Part 94 of ASP.NET Core tutorial.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("EditRolePolicy", policy => policy.RequireClaim("Edit Role"));
});
}
{
services.AddAuthorization(options =>
{
options.AddPolicy("EditRolePolicy", policy => policy.RequireClaim("Edit Role"));
});
}
To check if the signed-in user satisfies EditRolePolicy, inject IAuthorizationService service into the view
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService authorizationService;
@inject IAuthorizationService authorizationService;
Pass the user and the name of the policy as parameters to AuthorizeAsync() method of IAuthorizationService. Succeeded property returns true if the policy is satisfied, otherwise false.
@if ((await authorizationService.AuthorizeAsync(User, "EditRolePolicy")).Succeeded)
{
<a asp-controller="Administration" asp-action="EditRole"
asp-route-id="@role.Id" class="btn btn-primary">
Edit
</a>
}
Authorization checks in views alone is not enough
It's not enough if we just show or hide UI elements on the view. The respective controller actions must also be protected. Otherwise, the user can directly type the URL in the address bar and access the resources.
In our example, though Edit button is hidden, the user can directly type the following URL to get to the EditRole action
http://localhost:0001/Administration/EditRole/RoleIdGuidHere
Make sure to protect the respective controller action as well
[Authorize(Policy = "EditRolePolicy")]
public async Task<IActionResult> EditRole(string id)
{
// Code
}
public async Task<IActionResult> EditRole(string id)
{
// Code
}
Service injection in multiple views
If you need IAuthorizationService in multiple views, consider importing in _ViewImports.cshtml, so you do not have to import it in every individual view.
No comments:
Post a Comment