Ray Ray - 1 month ago 13
ASP.NET (C#) Question

ASP.NET Core policy base Authorize with RequireUser with string array

I am creating policy base authorization and would like to allow multiple users in one policy to access webpage.

I created policy like shown below in start up file. Question, How can I use multiple usernames in one policy? I looked at the method for

.RequireUserName
, it is only accepting string username.

Policy name
AdminServiceAccount
is mostly I am interested in to add multiple users. If I use param
.RequireUserName("DOMAIN\\USER1,DOMAIN\\USER2")
will it work? I don't think so, but wanted to check if there is an alternative way.

services.AddAuthorization(
option =>
{
option.AddPolicy("Admin", policy => policy.RequireRole("Domain\\GroupName"));
option.AddPolicy("SuperAdminUser", policy => policy.RequireUserName("DOMAIN\\SuperAdminUser"));
option.AddPolicy("AdminServiceAccount", policy => policy.RequireUserName("DOMAIN\\USER1"));
}
);


UPDATE 1:
enter image description here

UPDATE 2:

So in my Controller, I added
[Authorize(Policy = "UserNamesPolicy")]
as show below:

[Authorize(Policy = "UserNamesPolicy")]
public class ServersController : Controller
{
private readonly ServerMatrixDbContext _context;

public ServersController(ServerMatrixDbContext context)
{
_context = context;
}

// GET: Servers
public async Task<IActionResult> Index()
{
// Some code here
return View();
}
}


Here is my startup file:

services.AddAuthorization(
option =>
{
option.AddPolicy("UserNamesPolicy",
policy => policy.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1", "DOMAIN\\USER2"))
);
}
);
services.AddSingleton<IAuthorizationHandler, UserNamesRequirement();


For
.AddSingleTon
in startup file I get below error:

enter image description here

Here is the
handler
class:

public class UserNamesHandler : AuthorizationHandler<UserNamesRequirement>
{

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserNamesRequirement requirement)
{
var userName = context.User.FindFirst(ClaimTypes.NameIdentifier).Value;

if (requirement.Users.ToList().Contains(userName))
context.Succeed(requirement);
return Task.FromResult(0);
}
}


Here is is the UserNamesRequirement class:

public class UserNamesRequirement : IAuthorizationRequirement
{
public UserNamesRequirement(params string[] UserNames)
{
Users = UserNames;
}
public string[] Users { get; set; }
}


UPDATE 3: SOLVED!!!!

Here are few changes that were added from update 2:

In
UserNameshandler
class changed var userName to get values from
context.User.Identity.Name;


public class UserNamesHandler : AuthorizationHandler<UserNamesRequirement>
{

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserNamesRequirement requirement)
{
// var userName = context.User.FindFirst(ClaimTypes.NameIdentifier).Value;
var userName = context.User.Identity.Name;

if (requirement.Users.ToList().Contains(userName))
context.Succeed(requirement);
return Task.FromResult(0);
}
}


In StartUp class fixed from
services.AddSingleton<IAuthorizationHandler, UserNamesRequirement>();
to
services.AddSingleton<IAuthorizationHandler,UserNamesHandler>();


Thanks to Gevory. :)

Answer
public class UserNamesHandler : AuthorizationHandler<UserNamesRequirement>
{

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserNamesRequirement requirement)
    {


        var userName = context.User.FindFirst(ClaimTypes.NameIdentifier).Value;

        if(requirement.UserNames.ToList().Contains(userName))
            context.Succeed(requirement);
        return Task.CompletedTask(if it does not compile use Task.FromResult(0));
    }
}

public class UserNamesRequirement : IAuthorizationRequirement
{
    public UserNamesRequirement(params string[] UserNames)
    {
        UserNames = UserNames;
    }

    public string[] UserNames { get; set; }
}

in startup.cs add

public void ConfigureServices(IServiceCollection services)
{
            services.AddAuthorization(options =>
            {
                options.AddPolicy("UserNamesPolicy",
                                  policy => policy.Requirements.Add(new UserNamesRequirement("ggg","dsds")));
            });
           services.AddSingleton<IAuthorizationHandler, UserNamesHandler>()

}
Comments