0

I'm working on a Asp.Net Core project right now. I need to get UserId in a class named "CheckPermissions" which located inside a ClassLibrary named "Core", but I can't reach FindeFirestValue method! I've read some sulotions about how to do it but I didn't get any answers.

My CheckPermissions class is:

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Toplearn.Core.Services.Interfaces.CheckPermissions;
using Toplearn.DataLayer.Entities.Context;

namespace Toplearn.Core.Services.Services.CheckPermissions
{
    public class CheckPermissionServices : ICheckPermissionServices
    {
        private ToplearnContext _context;
        private IHttpContextAccessor _accessor;
        private IAccessorServices _accessorHttpContext;

        public CheckPermissionServices(ToplearnContext context, IHttpContextAccessor accessor)
        {
            _context = context;
            _accessor = accessor;
        }


        public bool CheckIsAllowedUser(int userId ,int givenPermissionId)
        {
            
            int userId = (int)_accessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifire);
            if (!_accessor.HttpContext.User.Identity.IsAuthenticated)
                return false;

            bool isExistUser = _context.Users.Any(u => u.UserId == userId);
            if (!isExistUser)
                return false;

            bool isExistAnyRole = _context.User_Roles.Any(ur => ur.UserId == userId);
            if (!isExistAnyRole)
                return false;

            List<int> RoleIds = _context.User_Roles.Where(ur => ur.UserId == userId)
                .Select(r => r.RoleId).ToList();

            bool isContainThisPermission = false;
            foreach (var item in RoleIds)
            {
                bool isExist = _context.RolePermissions.Any(rp => rp.RoleId == item && rp.PermissionId == givenPermissionId);
                if (isExist)
                {
                    isContainThisPermission = true;
                    break;
                }
             
            }
            if (!isContainThisPermission)
                return false;

            return true;

        }
    }
}

I've injected IHttpContextAccessor too, but I can't reach this method!

I tried to reach this method like bellow:

int userId = (int)_accessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifire);

So Does anyone have any sulotions for it?

Hossein
  • 142
  • 10
  • Make it `public`. In other assemblies only public types and members are visible. – Olivier Jacot-Descombes Sep 26 '21 at 15:43
  • @Olivier isn't it already public? How would OP see the method anywhere if it wasn't? – ProgrammingLlama Sep 26 '21 at 15:48
  • It appears to be an extension method on `ClaimsPrincipal` but neither `User` not `User.Identity` are derived from it. [Method docs](https://learn.microsoft.com/en-us/previous-versions/aspnet/mt173634(v=vs.108)) + [`User.Identity` docs](https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsprincipal.identity?view=net-5.0#System_Security_Claims_ClaimsPrincipal_Identity) – ProgrammingLlama Sep 26 '21 at 15:53
  • @Llama you say that there is no sulotions for that? (: – Hossein Sep 26 '21 at 21:48

1 Answers1

0

You could rewrite your code like this:

Claim identifierClaim = _accessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier);
int userId = int.Parse(identifierClaim.Value);

Note that:

  1. FindFirst returns a Claim, which can be null if the user doesn't have the claim in their collection of claims. You should write appropriate code to handle this scenario.

  2. If the value of this claim isn't an integer numeric value, you'll get a FormatException from int.Parse. I suggest using int.TryParse instead. See this answer for an example of that.

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86