Restrict model properties based on Authorization

Shant Hagopian 21 Reputation points
2022-05-05T22:10:11.397+00:00

I have the following model property

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? CommentsAdmins { get; set; }

Is it possible to overwrite the get value with null with something like this

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? CommentsAdmins 
{
    [Authorize(Policy = "Admins")]
    get;
    set; 
}

Currently I'm using the controller to assign null to the property based on the user Claim

if (userType != UserType.Admin.ToString())
{
    Job.CommentsAdmins = null;
}

Ultimately I want the API to omit the property in the response if the user does not have the required authorization level (Admin role)

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,361 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Zhi Lv - MSFT 32,076 Reputation points Microsoft Vendor
    2022-05-06T08:58:51.3+00:00

    Hi @Shant Hagopian ,

    The [Authorize] attribute was applied to a controller, action, or Razor Page, limits access to that component authenticated users, instead of the Property and its get and set methods.

    Ultimately I want the API to omit the property in the response if the user does not have the required authorization level (Admin role)

    From your description, you want to modify the response data based on the User's role. In this scenario, you could consider to use the Result filters to get the response data, then check the current user's role and based on the result to modify the response data. Like this:

    Create a CustomResultFilter class:

    using Microsoft.AspNetCore.Mvc;  
    using Microsoft.AspNetCore.Mvc.Filters;  
    using WebApplication2.Data;  
      
    namespace WebApplication2.Filters  
    {  
        public class CustomResultFilter : Attribute, IResultFilter  
        {  
            public void OnResultExecuting(ResultExecutingContext context)  
            {   
                var objResult = context.Result;  
                //get the API response data.  
                if (objResult is JsonResult json)  
                {  
                    var value = json.Value;  
                }  
      
                //get currennt user's claims  
                var currentUserCliaims = context.HttpContext.User?.Claims;  
      
                //loop through the user cliams and check if user in the role  
      
                //Then, modify the result data based on the user's role.  
      
                //return the updated result:  
                context.Result = new JsonResult(new User()  
                {  
                    Username = "List --- "  
                });   
            }  
      
            public void OnResultExecuted(ResultExecutedContext context)  
            {  
            }  
        }  
    }  
    

    Then, apply the CustomResultFilter on the API action method:

        [HttpGet("gerUser")]  
        [CustomResultFilter]  
        public IActionResult GerUser()  
        {  
            return new JsonResult(new User()  
            {  
                 ID = 1,  
                  Username="AA",  
                   WriterName="aa"  
            });  
        }  
    

    By using the above method, if you want to handle multiple properties or class, you might have to create multiple custom result filter. So, the easiest way might be is your currently used, to check the role in the action method:

     if (userType != UserType.Admin.ToString())  
     {  
         Job.CommentsAdmins = null;  
     }  
    

    You can choose them according to your actual situation.


    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

    0 comments No comments