Home > OS >  .NET core User Claims Reusability
.NET core User Claims Reusability

Time:03-05

I have been using Azure B2C authentication for a while. Whenever I need to identify the user that is logged in I can just call

User.Claims.FirstOrDefault(e => e.Type == ClaimConstants.ObjectId)?.Value

or when I need to get the user`s email I can just call

User?.Claims.Where(e => e.Type == "emails").Select(e => e.Value).FirstOrDefault();

Everything works fine and I can work with the user`s information however I noticed whenever I need to get some information about the user I need to repeat myself and use the lines above again and again. With multiple methods in a controller I can end up with a repetitive code. I can see that the User comes from the ControllerBase and it is a class called ClaimsPrincipal that contains ienumerable of <claims which I am using to identify the user. I would like to ideally create my own class that will be responsible for identifying those users or I would like to just instantiate this once in the controller and assign it to my property so I can reuse it. I tried to do this in the constructor of my controller and I was really surprised, it was null even after I successfully logged in with the user.

  private readonly string _userId;
   private readonly string _userEmail;


  public HomeMickeyMouseController(
            IRecaptchaTrashService recaptchaService,
            IOrderGarbageService orderService
        {
            _recaptchaService = recaptchaService;
            _orderService = orderService;               
            _userId = User?.Claims.FirstOrDefault(e => e.Type == ClaimConstants.ObjectId)?.Value;
            _userEmail = User?.Claims.Where(e => e.Type == "emails").Select(e => e.Value).FirstOrDefault(); //NULL EVEN AFTER LOGIN??!!! WHILE NOT NULL IN A METHOD?
        }



  public IActionResult Index()
        {
            var test = User.Claims.FirstOrDefault(e => e.Type == ClaimConstants.ObjectId)?.Value; //this is not NULL 
            return View();
        }

Is this possible to achieve this somehow, or do I have to just repeat User.Claims in every method of the controller? Thanks

CodePudding user response:

You need to use HttpContext to get the claim in your constructor.

private readonly IHttpContextAccessor _context;
//.........
    
public HomeMickeyMouseController(IHttpContextAccessor context)
        {
            //.........
            _context = context;

            var test = _context.HttpContext.User.Claims.Where(e => e.Type == "emails").Select(e => e.Value).FirstOrDefault();
        }
  • Related