locked
IsInRole Principle always throws error RRS feed

  • Question

  • User-183185495 posted

    For some reason this line is throwing a null i cant figure it out it appears to be the way this Iprincipal is being applied

     public static class HelperMethods  {
    public static bool IsInAnyRole(this IPrincipal principal, params string[] roles){ return roles.Any(principal.IsInRole); }
    }

    I am using it as such this is on my BaseController

     private  bool IsCurrentUserClubAdmin() {
      return User.IsInAnyRole(Constants.ClubSuperAdmin, Constants.ClubMod);          
    
      }

    My Constants is simply this

            public const string ClubMod = "ClubMod";
            public const string ClubAdmin = "Admin";
            public const string ClubUser = "ClubUser";
            public const string ClubSuperAdmin = "ClubSuperAdmin";
          
    



     

    And my user is indead an SuperAdmin

    My User table

    The problem is here 

         public static bool IsInAnyRole(this IPrincipal principal, params string[] roles)

    principal = null

    I think the issue comes from here

    public BaseController (){
      IsCurrentUserClubAdmin(};
    
    }

    I think the problem is the principle is not loaded by the time of the BaseController life cycle where can i call IsCurrentUserClubAdmin from

    Monday, March 8, 2021 3:03 PM

Answers

  • User475983607 posted

    roguenidb

    While True that handles the code behind it doesnt give a way to deal with the visual elements that you just want to turn of and on. It always sems to just show examples at controller or model level no view level interaction.

    That's not a correct statement.  Action methods invoke Views.  The Action method and the View have access to the user's claims and roles.  It is up to you to write the code.

    namespace IdentityMvc.Extensions
    {
        public static class HelperMethods
        {
            public static bool IsInAnyRole(this ClaimsIdentity principal, params string[] roles)
            {
                foreach (var role in roles)
                {
                    if(principal.Claims.Any(c => c.Type == ClaimTypes.Role && c.Value == role))
                    {
                        return true;
                    }
                }
                return false;
            }
        }
    }
    @using IdentityMvc.Extensions
    @{
        ViewData["Title"] = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h1>Index</h1>
    
    @if (((System.Security.Claims.ClaimsIdentity)User.Identity).IsInAnyRole("Admin", "User"))
    {
        <div>Admin or User</div>
    }
    else 
    { 
        <div>Some other role</div>
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, March 8, 2021 9:09 PM

All replies

  • User475983607 posted

    I think the problem is the principle is not loaded by the time of the BaseController life cycle where can i call IsCurrentUserClubAdmin from

    Typically, roles or claims policy based authorization solves this problem. 

    https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-5.0

    Monday, March 8, 2021 3:33 PM
  • User-183185495 posted

    roguenidb

    I think the problem is the principle is not loaded by the time of the BaseController life cycle where can i call IsCurrentUserClubAdmin from

    While True that handles the code behind it doesnt give a way to deal with the visual elements that you just want to turn of and on. It always sems to just show examples at controller or model level no view level interaction.

    Typically, roles or claims policy based authorization solves this problem. 

    https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-5.0

    Monday, March 8, 2021 4:27 PM
  • User475983607 posted

    roguenidb

    While True that handles the code behind it doesnt give a way to deal with the visual elements that you just want to turn of and on. It always sems to just show examples at controller or model level no view level interaction.

    That's not a correct statement.  Action methods invoke Views.  The Action method and the View have access to the user's claims and roles.  It is up to you to write the code.

    namespace IdentityMvc.Extensions
    {
        public static class HelperMethods
        {
            public static bool IsInAnyRole(this ClaimsIdentity principal, params string[] roles)
            {
                foreach (var role in roles)
                {
                    if(principal.Claims.Any(c => c.Type == ClaimTypes.Role && c.Value == role))
                    {
                        return true;
                    }
                }
                return false;
            }
        }
    }
    @using IdentityMvc.Extensions
    @{
        ViewData["Title"] = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h1>Index</h1>
    
    @if (((System.Security.Claims.ClaimsIdentity)User.Identity).IsInAnyRole("Admin", "User"))
    {
        <div>Admin or User</div>
    }
    else 
    { 
        <div>Some other role</div>
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, March 8, 2021 9:09 PM
  • User-183185495 posted

    So As long as I have those users in the user roles table you could should work is their any more setup that is required? 

    How do i add the users to a claim.

    Tuesday, March 9, 2021 10:43 AM
  • User-183185495 posted

    So As long as I have those users in the user roles table you could should work is their any more setup that is required? 

    How do i add the users to a claim.

    roguenidb

    While True that handles the code behind it doesnt give a way to deal with the visual elements that you just want to turn of and on. It always sems to just show examples at controller or model level no view level interaction.

    That's not a correct statement.  Action methods invoke Views.  The Action method and the View have access to the user's claims and roles.  It is up to you to write the code.

    namespace IdentityMvc.Extensions
    {
        public static class HelperMethods
        {
            public static bool IsInAnyRole(this ClaimsIdentity principal, params string[] roles)
            {
                foreach (var role in roles)
                {
                    if(principal.Claims.Any(c => c.Type == ClaimTypes.Role && c.Value == role))
                    {
                        return true;
                    }
                }
                return false;
            }
        }
    }
    @using IdentityMvc.Extensions
    @{
        ViewData["Title"] = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h1>Index</h1>
    
    @if (((System.Security.Claims.ClaimsIdentity)User.Identity).IsInAnyRole("Admin", "User"))
    {
        <div>Admin or User</div>
    }
    else 
    { 
        <div>Some other role</div>
    }

    Tuesday, March 9, 2021 10:43 AM
  • User475983607 posted

    So As long as I have those users in the user roles table you could should work is their any more setup that is required? 

    Yes.  The user account must have roles in the database.  

    How do i add the users to a claim.

    Use the Identity UserManager API.  I think you'll be interested in reading the openly published Identity documentation and going through a few tutorials.

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.usermanager-1?view=aspnetcore-5.0

    https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-5.0&tabs=visual-studio

        [Authorize]
        public class UserManagerController : Controller
        {
            private readonly UserManager<ApplicationUser> _userManager;
            public UserManagerController(UserManager<ApplicationUser> userManager)
            {
                _userManager = userManager;
            }
            public async Task<IActionResult> Index()
            {
                ApplicationUser user = await _userManager.FindByNameAsync(User.Identity.Name);
                IdentityResult results = await _userManager.AddClaimAsync(user, 
                    new System.Security.Claims.Claim("MyNewClaim", "Hello World"));
                return View();
            }
        }

    Keep in mind you should always check if the claim already exists before assigning a role.  The above is only an example.

    Tuesday, March 9, 2021 12:01 PM
  • User-183185495 posted

    Yeah am using the user manager already and identity its already working thank u u legend.

    Will figure out who u are some day lol

    roguenidb

    So As long as I have those users in the user roles table you could should work is their any more setup that is required? 

    Yes.  The user account must have roles in the database.  

    roguenidb

    How do i add the users to a claim.

    Use the Identity UserManager API.  I think you'll be interested in reading the openly published Identity documentation and going through a few tutorials.

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.usermanager-1?view=aspnetcore-5.0

    https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-5.0&tabs=visual-studio

        [Authorize]
        public class UserManagerController : Controller
        {
            private readonly UserManager<ApplicationUser> _userManager;
            public UserManagerController(UserManager<ApplicationUser> userManager)
            {
                _userManager = userManager;
            }
            public async Task<IActionResult> Index()
            {
                ApplicationUser user = await _userManager.FindByNameAsync(User.Identity.Name);
                IdentityResult results = await _userManager.AddClaimAsync(user, 
                    new System.Security.Claims.Claim("MyNewClaim", "Hello World"));
                return View();
            }
        }

    Keep in mind you should always check if the claim already exists before assigning a role.  The above is only an example.

    Tuesday, March 9, 2021 1:08 PM
  • User-183185495 posted

    Are u this guy if so would make allot of sense

    (7) Show or hide login and logout links based on login status in asp net core - YouTube

    Tuesday, March 9, 2021 4:06 PM