Authorization Using Windows Active Directory Groups In .NET Core 2 Razor Pages

In this article, you will learn about authorization using Windows Active Directory groups in .NET Core 2 Razor Pages.

In this article, I will provide information on how to authorize the logged in Windows users using Windows Active Directory groups in Razor pages. In order to see how to create a .NET Core web application with Razor pages and retrieve data from SQL Server using Entity Framework, you can visit my previous article.
 
Below are the software/concepts used in this document.
  1. Visual Studio 2019
  2. Razor Pages
  3. .Net Core 2.1
  4. Net Core Web Application
  5. C# Language

Introduction

 
The best practice for designing an application is to be very sure about the process by which we would be authenticating the user to log into the application and then, authorizing the user to use the functionalities of the application. In this article, I have already used Windows Authentication while creating the web application and now, I would be showcasing on how to use Windows Active Directory groups to authorize the logged in Windows user. Below is the step-by-step description on how to achieve this in .NET Core Razor Pages.
 

Open your project in Visual Studio 2019

 
In my case, I am opening the earlier created project where Razor pages are present.
 
Authorization using Windows Active Directory Groups in NET Core 2 Razor Pages
 

Ways to achieve authorization in .NET Core Web Application

 
There are multiple ways to achieve authorization like using Custom role-based authorization, using policy-based authorization, simply calling method to check if the user is authorized to access the method or not, etc. Here, we will be discussing the below two ways.
  1. Using a custom role-based authorization.
  2. Using a custom method to check if logged in user is part of Windows AD Group or not.

Custom role-based authorization in .NET Core Web Application

  1. Create a new class which would extend the IClaimsTransformation.
    1. public class ClaimsTransformer : IClaimsTransformation  
    2. {  
    3.     public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)  
    4.     {  
    5.         var wi = (WindowsIdentity)principal.Identity;  
    6.         if (wi.Groups != null)  
    7.         {  
    8.             foreach (var group in wi.Groups) //-- Getting all the AD groups that user belongs to---  
    9.             {  
    10.                 try  
    11.                 {  
    12.                     var claim = new Claim(wi.RoleClaimType, group.Value);  
    13.                     wi.AddClaim(claim);                          
    14.                 }  
    15.                 catch (Exception ex)  
    16.                 {  
    17.                     throw ex;  
    18.                 }  
    19.             }  
    20.         }              
    21.         return Task.FromResult(principal);  
    22.     }  
    23. }  
  2. Add the below line to your configureService method in Startup.cs as you have created your own class extending the IClaimsTransformation.
    1. services.AddSingleton<IClaimsTransformation, ClaimsTransformer>();  
  3. In your Controller, add the “Authorize” line to get the authorization in place for every method where you want to implement the authorization.
    1. [Route("api/[controller]/[action]")]  
    2.     [ApiController]  
    3.     public class MYListsController : ControllerBase  
    4.     {  
    5.         [Authorize(Roles = "Admin")]  
    6.         [HttpGet]  
    7.         [ActionName("GetMyList")]  
    8.         public bool GetMyList()  
  1. Test the functionality by debugging. In my example, I am a part of “Admin” Windows AD Group. Hence, while debugging, I reach the “GetMyList” method. If I change the “Authorize” line to [Authorize(Roles = "Contribute")], it does not even reach the “GetMyList” method as I am not part of this Windows AD Group.

  2. Similarly, the Authorize line can be used for entire PageModel in Razor Pages as we don’t have a way as of now to authorize any action inside the Page Model.

Custom method to authorize the user in .NET Core Web Application

  1. Create a new class in your .NET Core web application and have a method to check if the current user is a part of AD Group or not. In my example, I have created a class with the name “Security”.
    1. public static class Security  
    2. {  
    3.     public static bool IsInGroup(ClaimsPrincipal User, string GroupName)  
    4.     {  
    5.         bool check = false;  
    6.         var user = (WindowsIdentity)User.Identity;  
    7.         if (user.Groups != null)  
    8.         {  
    9.             foreach (var group in user.Groups)  
    10.             {  
    11.                 check = group.Translate(typeof(NTAccount)).ToString().Contains(GroupName);  
    12.                 if (check)  
    13.                     break;  
    14.             }  
    15.         }  
    16.         return check;  
    17.     }  
    18. }  
  2. In your Controller, you can call this method to check the user and then, based on the output, you can extend the functionality.
    1. [HttpGet]  
    2.         [ActionName("GetMyList")]  
    3.         public bool GetMyList()  
    4.         {  
    5.             var check = Security.IsInGroup(User, "Admin");//--- Returning true as I am not part of Contribute AD Group  
    6.             var check1 = Security.IsInGroup(User, "Contribute"); //--- Returning false as I am not part of Contribute AD Group  
    7.             return check;  
    8.         }.  
  3. Test the functionality by debugging. In my example, I am a part of “Admin” Windows AD Group. Hence, while debugging, I am getting True for the first line but for the second line, (Security.IsInGroup(User,”Contribute”); I am getting False as I am not part of this Windows AD Group.

  4. Similarly, the Security.IsInGroup method can be called from PageModel as well in Razor Pages to authorize the user.
That is it. I hope you have learned something new from this article and will utilize this in your work.