question

Brian-7574 avatar image
0 Votes"
Brian-7574 asked ZhiLv-MSFT answered

Role-based authorization from Database?

I'm working on a large .NET 5 razor pages application with a reporting feature (about 45 reports) and about 9 different user roles. Each user role has access to certain reports. I believe I can allow and restrict access using role page authorization in my Page Model:

 [Authorize(Roles = "Role1, Role2, Role4")]
 public class public class Report1 : PageModel
 {
 }

However, instead of manually coding each role like this for 45 different reports, can I pull the roles from my database? For simplicity, lets stay I have a Roles table which stores data as:

Report Role
Report1 Role1
Report1 Role2
Report1 Role4


dotnet-aspnet-core-razor
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

However, instead of manually coding each role like this for 45 different reports, can I pull the roles from my database?

.NET 5 has many options like policy based authorization. Take a look at the official authorization docs and find an approach that best fits your requirements.


0 Votes 0 ·

Thanks, I looked through it but I didn't see anything about creating authorization permissions from a database table. It's important for the authorization to be based on the database table so the site admins can modify the permissions for different reports when needed. (They should be able to modify access from a web page instead of a programmer needing to go in and modify code)

0 Votes 0 ·

Thanks, I looked through it but I didn't see anything about creating authorization permissions from a database table.

Correct. The policy based authorization pattern provides a place where you get to write custom logic. Your custom logic can query the database and verify the current user has access to the currently requested report.

You can also write authorization middleware which might be more appropriate. You'll fetch the current URL and make sure the user has access to the endpoint. I would use a claim rather than a role but a role will work. you just need a table that relates roles to endpoints.


0 Votes 0 ·

1 Answer

ZhiLv-MSFT avatar image
0 Votes"
ZhiLv-MSFT answered

Hi @Brian-7574,

You can create a custom Authorization attribute, in its OnAuthorization method, you could get the current login username, then based on the username to find the relates roles and check whether it has permission to access the action method.

Please refer the following sample code:

Create a RoleAuthorizeAttribute:

    [AttributeUsage(AttributeTargets.Class |AttributeTargets.Method)]
     public class RoleAuthorizeAttribute : Attribute, IAuthorizationFilter
     {
         public string currentReport;
         public RoleAuthorizeAttribute(string CurrentReport)
         {
             currentReport = CurrentReport;
         }
    
         /// <summary>  
         /// This will Authorize User  
         /// </summary>  
         /// <returns></returns>  
         public async void OnAuthorization(AuthorizationFilterContext filterContext)
         {  
             var _dbcontext = filterContext.HttpContext
             .RequestServices
             .GetService(typeof(ApplicationDbContext)) as ApplicationDbContext;
    
             if (filterContext != null)
             {
                 //get current login username
                 var username = filterContext.HttpContext.User.Identity.Name;
    
                 //get the current report name.
                 var reportname = currentReport; 
    
                 //get current user
                 //var users = _dbcontext.Users.Where(c => c.UserName == username).FirstOrDefault();
    
                 // according to the username and report name to query database via the _dbcontext, and then check whether the user has permission to access the report.
                 //based on the result to continue or return the Unauthorized message.
                 if (username != null)
                 { 
                        //validate success
                 }
                 else
                 {
                     filterContext.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized };
                 }
             }
         } 
     }

Apply the custom attribute on the action method:

     [RoleAuthorize("report1")]
     public IActionResult Privacy()
     {
         
         return View();
     }

The screenshot as below:

147332-1.gif


If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Best regards,
Dillion



1.gif (186.2 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.