(C# ASP.NET Core) Configuring Role based Authorization

This is an explanation of how an "Area" based ASP.NET Core project can be configured for role and policy based authorization. Authorization can be applied to the entire "Area" directory. We also explain how to specify the login and access denied pages.
(Rev. 19-Mar-2024)

Categories | About |     |  

Parveen,

What is a "Role"?

In simplest terms a role refers to a certain class of users of your website. For example, all doctors can be identified with a role, say, "doctor" - which could be any valid string identifier. Similarly, all patients might be identified with a role, say, "customer".

If a website has certain pages that are relevant only for doctors, then we would like to define rules that restrict access only to the users of a particular role. This is done through configuration, explained next.

Video Explanation

Please watch the following youtube video:

How to Configure Area specific Authorization
(see the linked video for first-hand explanation)

Step 1: Add an authorization policy to the services collection. In the code below we define two policies "pdoctor" and "ppatient", each attached, respectively, to the roles "doctor" and "patient".

public void ConfigureServices(IServiceCollection services)
{

  //  ------- code not shown -------- 

  // Step 1: Add an authorization policy 
  services.AddAuthorization(opt =>
  {

    // one policy for role "doctor" 
    opt.AddPolicy("pdoctor",
    policy => { policy.RequireRole("doctor"); });

    // another policy for role "patient" 
    opt.AddPolicy("ppatient",
    policy => { policy.RequireRole("patient"); });


    // NOTE: these roles are set 
    // at the time of login. we 
    // shall discuss that later 
  });


  //  ------- code not shown -------- 
}

Step 2: Apply policy to Area folders. Policy is applied to all files and subdirectories in an Area folder.

public void ConfigureServices(IServiceCollection services)
{


  //  ------- code not shown -------- 

  // Step 2: Add policy to the entire area 
  services.AddRazorPages(
  opt =>
  {

    // the first arg is area, second must be slash, 
    // and the third is the policy 
    opt.Conventions.AuthorizeAreaFolder("doctor", "/", "pdoctor");

    opt.Conventions.AuthorizeAreaFolder("patient", "/", "ppatient");

  }

  );


  //  ------- code not shown -------- 
}

Step 3: Configure paths to the login and access denied pages.

public void ConfigureServices(IServiceCollection services)
{


  //  ------- code not shown -------- 

  // Step 3: specify access deinied and login pages 
  services
  .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
  .AddCookie(options =>
  {

    options.LoginPath = "/Login";

    options.AccessDeniedPath = "/Login";

  }

  );


  //  ------- code not shown -------- 
}

Step 4: Add Cookie, Authentication and Authorization middlewares to the pipeline.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{


  //  ------- code not shown -------- 

  // enable cookie policy 
  app.UseCookiePolicy(new CookiePolicyOptions()
  {

    // this setting breaks OAuth2 and other cross-origin 
    // authentication schemes, it elevates the 
    // level of cookie security for other types of apps 
    MinimumSameSitePolicy = SameSiteMode.Strict
  });

  app.UseAuthentication();

  app.UseAuthorization();


  //  ------- code not shown -------- 
}

The completed Startup class

This is the completed startup class

public class Startup
{

  public void ConfigureServices(IServiceCollection services)
  {


    // Step 1: Add an authorization policy 
    services.AddAuthorization(opt =>
    {

      // one policy for role "doctor" 
      opt.AddPolicy("pdoctor",
      policy => { policy.RequireRole("doctor"); });

      // another policy for role "patient" 
      opt.AddPolicy("ppatient",
      policy => { policy.RequireRole("patient"); });

    });


    // Step 2: Add policy to the entire area 
    services.AddRazorPages(
    opt =>
    {

      // the first arg is area, second must be slash, 
      // and the third is the policy 
      opt.Conventions.AuthorizeAreaFolder("doctor", "/", "pdoctor");

      opt.Conventions.AuthorizeAreaFolder("patient", "/", "ppatient");

    }

    );

    // Step 3: specify access deinied and login pages 
    services
    .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {

      options.LoginPath = "/Login";

      options.AccessDeniedPath = "/Login";

    }

    );

  }

  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  {

    if (env.IsDevelopment())
    {

      app.UseDeveloperExceptionPage();

    }

    app.UseStaticFiles();

    app.UseRouting();

    app.UseCookiePolicy(new CookiePolicyOptions()
    {

      // this setting breaks OAuth2 and other cross-origin 
      // authentication schemes, it elevates the 
      // level of cookie security for other types of apps 
      MinimumSameSitePolicy = SameSiteMode.Strict
    });

    app.UseAuthentication();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {

      endpoints.MapRazorPages();

    });

  }

}


This Blog Post/Article "(C# ASP.NET Core) Configuring Role based Authorization" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.