Home > Blockchain >  Can't access Claim by it's key after login with ASP.NET Core Identity in .NET 6 Project
Can't access Claim by it's key after login with ASP.NET Core Identity in .NET 6 Project

Time:08-11

I have a Blazor project in .NET 6. I am using ASP.NET Core Identity for login. After login, I have set some Claims with a custom Key. Here is the code:

Login Code:

var createdUser = await _userManager.FindByNameAsync(Input.UserName.Trim());

var LoginResult = await _signInManager.PasswordSignInAsync(Input.UserName, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (LoginResult.Succeeded)
{
    var userRoles = await _userManager.GetRolesAsync(createdUser);
    
    var claims = new List<Claim>()
    {
        new Claim("UserId", createdUser?.Id),
        new Claim("Username", createdUser?.UserName),
        new Claim("OrganizationId", createdUser?.OrganizationId)
    };

    if(userRoles!= null && userRoles.Count > 0)
    {
        foreach (var role in userRoles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role));
        }
    }   

    var appIdentity = new ClaimsIdentity(claims);
    var claimPrincpal = new ClaimsPrincipal(appIdentity);
    Thread.CurrentPrincipal = claimPrincpal;
    User.AddIdentity(appIdentity);
    
    return LocalRedirect(returnUrl);
}

After Login I have a UserInfoService class and there I have some code to get the Claim value. Here is the code below:

public class UserInfoService : IUserInfoService
{
    private readonly AuthenticationStateProvider _authProvider;
    private readonly UserManager<ApplicationUser> _userManager;
    
    public UserInfoService(
        AuthenticationStateProvider authProvider,
        UserManager<ApplicationUser> userManager)
    {
        _authProvider = authProvider;
        _userManager = userManager;
    }
           

    public async Task<string> GetUserName()
    {
        var auth = await _authProvider.GetAuthenticationStateAsync();
        var user = auth.User;

        if (!user.Identity.IsAuthenticated)
        {
            return null;
        }
        else
        {
            var claimsIdentity = user.Identity as ClaimsIdentity;
            var userName = claimsIdentity.FindFirst("Username")?.Value;

            if (string.IsNullOrWhiteSpace(userName))
                return null;

            return userName;
        }
    }        
}

And In my Program.cs file I have the below settings for identity:

builder.Services.AddIdentity<ApplicationUser, ApplicationRole>(options => options.SignIn.RequireConfirmedAccount = false)
           .AddRoles<ApplicationRole>()
           .AddEntityFrameworkStores<ApplicationDbContext>()
           .AddDefaultTokenProviders();

But whenever I call GetUserName method to get the username from Claim, it returns null. I tried to debug the code and during debugging whenever the breakpoint comes upon this line (var claimsIdentity = user.Identity as ClaimsIdentity;), I hover the mouse and have the below information into the Claims Property, which I don't understand how to access. I don't even see the Claims Key (UserId, Username) which I set during the login. enter image description here

Can anyone help to find the answer to how can I access Claims Key and Value?

CodePudding user response:

var appIdentity = new ClaimsIdentity(claims);
var claimPrincpal = new ClaimsPrincipal(appIdentity);
Thread.CurrentPrincipal = claimPrincpal;
User.AddIdentity(appIdentity);

By using the above code, the new claim will be added to the HttpContext.User, it will store data while processing a single request. The collection's contents are discarded after a request is processed.

So, I suggest you can store the Claims in the AspNetUserClaims table, you could use the UserManager.AddClaimAsync() method to add the specified claim to the user, and then use the SignInManager or ApplicationDbContext to get tye user's claims. Check the following sample code (Login post method):

var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
    //find current user.
    var user = await _userManager.FindByEmailAsync(Input.Email);
    //based on user information to query the user and role policy table. Here I set the user role directly.
    var userrole = "User";
    if (user.UserName.Contains("aa"))
    {
        userrole = "Admin";
    }

    //get the current user claims principal
    var claimsPrincipal = await _signInManager.CreateUserPrincipalAsync(user);
    //get the current user's claims.
    var claimresult = claimsPrincipal.Claims.ToList();
    //it it doesn't contains the Role claims, add a role claims
    if (!claimresult.Any(c => c.Type == ClaimTypes.Role))
    { 
        //add claims to current user. 
        await _userManager.AddClaimAsync(user, new Claim(ClaimTypes.Role, userrole));
    }
    //refresh the Login
    await _signInManager.RefreshSignInAsync(user);
     
    _logger.LogInformation("User logged in.");
    return LocalRedirect(returnUrl);
}
  • Related