how to set authorize for each page and each module?

mc 3,641 Reputation points
2023-06-07T04:14:40.96+00:00

If I have several pages like users.cshtml,orders.cshtml,products.cshtml

how to set the authorize for each user to each page?

If I want to user1 have orders.cshtml read authority but he can not update and delete.

user2 has orders.cshtml read update but not delete.

user3 has products.cshtml read update and delete.

if he can not delete then hide the button

how to design the authority?

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

Accepted answer
  1. Ruikai Feng - MSFT 2,526 Reputation points Microsoft Vendor
    2023-06-08T08:22:41.58+00:00

    Hi,@mc,You could try claim based authorization as AgaveJoe suggested,and custom Authorization Providers to avoid registing plenty of policies statically ,a minimal example as below:

    public static class PolicyGenerator 
        {
            public const string Prefix = "Permit";
            public const string Separator = "_";        
            
        }
        public class PermissionAuthorizeAttribute : AuthorizeAttribute
        {
           
            public PermissionAuthorizeAttribute(string controller,string action)
            {
                
                Policy = $"{PolicyGenerator.Prefix}{PolicyGenerator.Separator}{controller}{PolicyGenerator.Separator}{action}";
            }        
        }
        public class PermissionRequirement : IAuthorizationRequirement
        {
            
            
            public string Controller { get; }
            
            public string Action { get; }
            public string Permission { get; }
            public PermissionRequirement(
                string controller, string action)
            {
                
                Controller = controller;
                Action = action;
                Permission = $"{PolicyGenerator.Prefix}{PolicyGenerator.Separator}{controller}{PolicyGenerator.Separator}{action}";
            }
        }
        public class PermissionAuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider
        {
            public PermissionAuthorizationPolicyProvider(
                IOptions<AuthorizationOptions> options) : base(options) { }
            public override async Task<AuthorizationPolicy?> GetPolicyAsync(
                string policyName)
            {
                if (!policyName.StartsWith(PolicyGenerator.Prefix, StringComparison.OrdinalIgnoreCase))
                    return await base.GetPolicyAsync(policyName);
                
                //  extract the permissions from the policyname ,you could modify the method for your requirement
                string[] permissions = GetPermissionsFromPolicy(policyName);
                
                var requirement = new PermissionRequirement(permissions[1], permissions[2]);
                // create a policy, add the requirement
                return new AuthorizationPolicyBuilder()
                    .AddRequirements(requirement).Build();
            }
            public string[] GetPermissionsFromPolicy(string policyName)
            {
                return policyName.Split(PolicyGenerator.Separator);
            }
        }
        public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
        {
            protected override Task HandleRequirementAsync(
                AuthorizationHandlerContext context, PermissionRequirement requirement)
            {
                          
                    if (context.User.HasClaim("Permission", requirement.Permission))
                    {
                        
                        context.Succeed(requirement);
                        return Task.CompletedTask;
                    }
                
               
                context.Fail();
                return Task.CompletedTask;
            }
        }
    

    Regist the services:

    builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(.....);
    builder.Services.AddAuthorization();
    builder.Services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
    // Overrides the DefaultAuthorizationPolicyProvider with our own
    builder.Services.AddSingleton<IAuthorizationPolicyProvider, PermissionAuthorizationPolicyProvider>();
    

    Tried with CookieAuthentication:

    [HttpPost]
            public async Task<IActionResult> Login(string User,string Controller,string Action)
            {
                await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, User),
                //you could add your logical to allow different user visit different endpoint here
                new Claim("Permission", $"{PolicyGenerator.Prefix}{PolicyGenerator.Separator}{Controller}{PolicyGenerator.Separator}{Action}"),
                //You could add the claim again with different value for other endpoint
                 new Claim("Permission", "Permit_Product_Create"),
               
            };
                var claimsIdentity = new ClaimsIdentity(
                    claims, CookieAuthenticationDefaults.AuthenticationScheme);
                var authProperties = new AuthenticationProperties
                {
                    
                };
                await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme,
                    new ClaimsPrincipal(claimsIdentity),
                    authProperties);
                return Ok("Ok");
            }
    

    Attach the custom Attribute to your actions accroding to the name of controller/action

    Result:

    6.8

    If you want to hide some content for not authorized User,You could try with View-Based Authorization

    For example:

    @using Microsoft.AspNetCore.Authorization
    @inject IAuthorizationService AuthorizationService
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Product</h1>
    
    
    
    @if ((await AuthorizationService.AuthorizeAsync(User, "Permit_Product_Create")).Succeeded)
    {
        <p>Create</p>
    }
    
    @if ((await AuthorizationService.AuthorizeAsync(User, "Permit_Product_Delete")).Succeeded)
    {
        <p>Delete</p>
    }
    @if ((await AuthorizationService.AuthorizeAsync(User, "Permit_Product_Update")).Succeeded)
    {
        <p>Update</p>
    }
    

    Result:

    6.8.1

    0 comments No comments

0 additional answers

Sort by: Most helpful