Quantcast
Channel: CodeProject Latest postings for ASP.NET
Viewing all articles
Browse latest Browse all 3938

"Context.UserIdentifier" of SignalR is always null when I use CustomAuthenticationStateProvider in Blazor Server App

$
0
0
I'm working on Blazor server App project. I have the following codes for CustomAuthenticationStateProvider:

CustomAuthenticationStateProvider.cs

publicclass CustomAuthenticationStateProvider : AuthenticationStateProvider
    {privatereadonly ProtectedSessionStorage _sessionStorage;private ClaimsPrincipal _anonymous = new ClaimsPrincipal(new ClaimsIdentity());public CustomAuthenticationStateProvider(ProtectedSessionStorage sessionStorage)
        {
            _sessionStorage = sessionStorage;
        }publicoverrideasync Task<AuthenticationState> GetAuthenticationStateAsync()
        {try
            {var userSessionStorageResult = await _sessionStorage.GetAsync<UserSession>("UserSession");var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null;if (userSession == null)
                {returnawait Task.FromResult(new AuthenticationState(_anonymous));
                }var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> {new Claim(ClaimTypes.Name, userSession.Username),new Claim(ClaimTypes.Role, userSession.UserRole),new Claim(ClaimTypes.NameIdentifier, userSession.UserId.ToString())
            }, "Jwt"));returnawait Task.FromResult(new AuthenticationState(claimsPrincipal));
            }catch (Exception)
            {returnawait Task.FromResult(new AuthenticationState(_anonymous));
            }
        }publicasync Task UpdateAuthenticationState(UserSession userSession)
        {
            ClaimsPrincipal claimsPrincipal;if (userSession != null)
            {await _sessionStorage.SetAsync("UserSession", userSession);await _sessionStorage.SetAsync("Token", userSession.TokenText);
                claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
                {new Claim(ClaimTypes.Name, userSession.Username),new Claim(ClaimTypes.Role, userSession.UserRole),new Claim(ClaimTypes.NameIdentifier, userSession.UserId.ToString())
                }));
            }else
            {await _sessionStorage.DeleteAsync("UserSession");
                claimsPrincipal = _anonymous;
            }

            NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(claimsPrincipal)));
        }
    }


UserSession.cs

publicclass UserSession
{publicint UserId { get; set; }publicstring Username { get; set; }publicstring UserRole { get; set; }publicstring Name { get; set; }publicstring TokenText { get; set; }
}


LoginController:

[Route("api/[controller]/[action]")]
    [ApiController]publicclass ApiLoginController : ControllerBase
    {privatereadonly SqliteContext _sqlServerContext;privatereadonly IConfiguration _configuration;privatereadonly IUserService _userService;public ApiLoginController(SqliteContext sqlServerContext, IConfiguration configuration, IUserService userService)
        {
            _sqlServerContext = sqlServerContext;
            _configuration = configuration;
            _userService = userService;
        }

        [HttpPost]
        publicasync Task<IActionResult> LoginSystem([FromBody] UserLoginVM loginModel)
        {var user = await _sqlServerContext.Users.Include(x => x.RoleRefNavigation)
                .FirstOrDefaultAsync(x => x.Username == loginModel.Username && x.IsActive);if (user == null)
            {return BadRequest("Invalid credentials.");
            }if (!MatchPasswordHash(loginModel.Password, user.Password, user.SaltPassword))
            {return BadRequest("Invalid credentials.");
            }if (!user.IsActive)
            {return StatusCode(403, "User is not active.");
            }if (user.IsLocked)
            {
                DateTime setDate = (DateTime)user.LockUntil;
                DateTime current = DateTime.Now;if (setDate > current)
                {return StatusCode(403, "User is restricted.");
                }await _userService.UnsetUserLimits(user.UserId);
            }

            user.RoleRefNavigation = await _sqlServerContext.Roles.FirstOrDefaultAsync(x => x.RoleId == user.RoleRef);string token = CreateToken(user);var data = new
            {
                tokenText = token,
                username = user.Username,
                userId = user.UserId.ToString(),
                name = user.Name,
                role = user.RoleRefNavigation.User_Role
            };await _userService.RegisterLoginTime(user.UserId);return Ok(data);
        }privatestring CreateToken(User user)
        {
            List<Claim> claims = new List<Claim>()
            {new Claim(ClaimTypes.NameIdentifier, user.Username),new Claim(ClaimTypes.Role, user.RoleRefNavigation.User_Role),new Claim(type: "UserId", value: user.UserId.ToString())
            };var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.GetSection("Jwt:Key").Value!));var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);var token = new JwtSecurityToken(
                claims: claims,
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Issuer"],
                expires: DateTime.Now.AddHours(8),
                signingCredentials: creds
                );var jwt = new JwtSecurityTokenHandler().WriteToken(token);return jwt;
        }privatebool MatchPasswordHash(string passwordText, byte[] password, byte[] passwordKey)
        {using (var hmac = new HMACSHA512(passwordKey))
            {var passwordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(passwordText));for (int i = 0; i < passwordHash.Length; i++)
                {if (passwordHash[i] != password[i])
                    {returnfalse;
                    }
                }returntrue;
            }
        }
    }


The problem is that when I check Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value; in SignalR hub, Context.UserIdentifier is always null. How can I fix this?

Viewing all articles
Browse latest Browse all 3938

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>