0

I am using .NET Core with Vue.JS

I want to know in my view by which role user is verified

What I have now

Controller

[Authorize(Roles = Roles.R)]
[Authorize(Roles = Roles.F)]
[Authorize(Roles = Roles.Admin)]
public IActionResult Index()
{
    return View();
}

[HttpGet]
[Route("IsAdmin")]
[Authorize(Roles = Roles.Admin)]
public IActionResult IsAdmin()
{            
    return Ok(true);
}

[HttpGet]
[Route("IsFull")]
[Authorize(Roles = Roles.F)]
public IActionResult IsFull()
{
    return Ok(true);
}

[HttpGet]
[Route("IsRead")]
[Authorize(Roles = Roles.R)]
public IActionResult IsRead()
{
    return Ok(true);
}

View

let vm = this;
jQuery.ajax({
    url: '/IsAdmin',
    type: "GET",
    success: function (result) {
        vm.isAdmin = true;
    },
    error: function (result) {
    },
    async: false
});

jQuery.ajax({
    url: '/IsFull',
    type: "GET",
    success: function (result) {
        vm.isFull = true;
    },
    error: function (result) {
    },
    async: false
});

jQuery.ajax({
    url: '/IsRead',
    type: "GET",
    success: function (result) {
        vm.isRead = true;
    },
    error: function (result) {
    },
    async: false
});

I know this looks terrible and probably it is terrible approach, but I don't have any better idea.

I addition. For handling roles I am using custom AuthorizationHandler because I need to combine RolesPrefix from configuration.

Custom AuthorizationHandler

public Task HandleAsync(AuthorizationHandlerContext authContext)
{
    var succeed = false;

    var pendingRequirements = authContext.PendingRequirements.ToList();

    var requiredRoles = new List<RoleRequirement>();

    foreach (var requirement in pendingRequirements)
    {
        requiredRoles.AddRange(((RolesAuthorizationRequirement)requirement).AllowedRoles.Select(x => new RoleRequirement(x)).ToList());
    }

    foreach (var role in requiredRoles)
    {
        if (role is RoleRequirement requirement)
        {
            var prefix = _configuration.GetValue<string>("RolesPrefix");

            if (authContext.User.IsInRole(prefix + requirement.Role))
            {
                succeed = true;
            }
        }
    };

    if (succeed)
    {
        MakeRequirementsSucceed(authContext);
    }         

    return Task.CompletedTask;
}

private static void MakeRequirementsSucceed(AuthorizationHandlerContext authContext)
{
    authContext.PendingRequirements.ToList().ForEach(x => authContext.Succeed(x));
}

What I think will be better

[Authorize(Roles = Roles.R)]
[Authorize(Roles = Roles.F)]
[Authorize(Roles = Roles.Admin)]
public IActionResult Index()
{
    var prefix = GetPrefixFromConfig();
    var isAdmin = User.IsInRole(prefix + Roles.Admin);
    var isFull = User.IsInRole(prefix + Roles.F);
    var isRead = User.IsInRole(prefix + Roles.R);
    
    return View(new { isAdmin, isFull, isRead });
}

Obviously provided example (pseudocoded) is not working due to IsInRole method always return null for some reason.

Could you show and expain to me better solution for this problem? I would appreciate your answer

Grzegorz G.
  • 1,285
  • 2
  • 14
  • 27
  • How does your custom AuthorizationHandler look? For the IsInRole method to work, you need to add the roles as claims to the ClaimsPrincipal – fbede Dec 29 '21 at 14:47
  • @fbede I added code that u are asking for. Could you please provide an example code of that what you are talking about? – Grzegorz G. Dec 29 '21 at 15:50

1 Answers1

0

As solution. I used How to check if user is member of group accepted answer by Nan Yu and then:

var prefix = _configuration.GetValue<string>("RolesPrefix");
var isAdmin = User.IsInGroup(prefix + Roles.Admin);
var isRead = User.IsInGroup(prefix + Roles.R);
var isFull = User.IsInGroup(prefix + Roles.F);

This will only work for WindowsAuthentication (which I am using)

Grzegorz G.
  • 1,285
  • 2
  • 14
  • 27