"Context.UserIdentifier" of SignalR is always null when I use CustomAuthenticationStateProvider in Blazor Server App
-
I'm working on Blazor server App project. I have the following codes for CustomAuthenticationStateProvider: CustomAuthenticationStateProvider.cs
public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly ProtectedSessionStorage _sessionStorage;
private ClaimsPrincipal _anonymous = new ClaimsPrincipal(new ClaimsIdentity());
public CustomAuthenticationStateProvider(ProtectedSessionStorage sessionStorage)
{
_sessionStorage = sessionStorage;
}public override async Task GetAuthenticationStateAsync() { try { var userSessionStorageResult = await \_sessionStorage.GetAsync("UserSession"); var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null; if (userSession == null) { return await Task.FromResult(new AuthenticationState(\_anonymous)); } var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List { new Claim(ClaimTypes.Name, userSession.Username), new Claim(ClaimTypes.Role, userSession.UserRole), new Claim(ClaimTypes.NameIdentifier, userSession.UserId.ToString()) }, "Jwt")); return await Task.FromResult(new AuthenticationState(claimsPrincipal)); } catch (Exception) { return await Task.FromResult(new AuthenticationState(\_anonymous)); } } public async 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 { 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;
-
I'm working on Blazor server App project. I have the following codes for CustomAuthenticationStateProvider: CustomAuthenticationStateProvider.cs
public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly ProtectedSessionStorage _sessionStorage;
private ClaimsPrincipal _anonymous = new ClaimsPrincipal(new ClaimsIdentity());
public CustomAuthenticationStateProvider(ProtectedSessionStorage sessionStorage)
{
_sessionStorage = sessionStorage;
}public override async Task GetAuthenticationStateAsync() { try { var userSessionStorageResult = await \_sessionStorage.GetAsync("UserSession"); var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null; if (userSession == null) { return await Task.FromResult(new AuthenticationState(\_anonymous)); } var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List { new Claim(ClaimTypes.Name, userSession.Username), new Claim(ClaimTypes.Role, userSession.UserRole), new Claim(ClaimTypes.NameIdentifier, userSession.UserId.ToString()) }, "Jwt")); return await Task.FromResult(new AuthenticationState(claimsPrincipal)); } catch (Exception) { return await Task.FromResult(new AuthenticationState(\_anonymous)); } } public async 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 { 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;
Quote:
private bool 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])
{
return false;
}
}
return true;
}
}Not an answer to your question, but that code is potentially vulnerable to a timing attack[^]. Although the salt may render it harder for an attacker to exploit, it would be better to avoid the early return - you always want this function to compare the full length of the arrays, not just the first
n
bytes.bool areEqual = true;
for (int i = 0; i < passwordHash.Length; i++)
{
if (passwordHash[i] != password[i])
{
areEqual = false;
}
}return areEqual;
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer