Click here to Skip to main content
15,796,456 members
Home / Discussions / ASP.NET
   

ASP.NET

 
PinnedHOW TO ANSWER A QUESTION PinPopular
Chris Maunder12-Jul-09 23:39
cofounderChris Maunder12-Jul-09 23:39 
QuestionCoding Help Pin
appache0524-Nov-23 19:04
appache0524-Nov-23 19:04 
AnswerRe: Coding Help Pin
Richard MacCutchan24-Nov-23 23:05
mveRichard MacCutchan24-Nov-23 23:05 
AnswerRe: Coding Help Pin
Andre Oosthuizen25-Nov-23 2:24
mveAndre Oosthuizen25-Nov-23 2:24 
AnswerRe: Coding Help Pin
jschell25-Nov-23 8:02
jschell25-Nov-23 8:02 
QuestionWhat should I start reading to get to where I want to go? Pin
DalTXColtsFan21-Nov-23 12:46
DalTXColtsFan21-Nov-23 12:46 
AnswerRe: What should I start reading to get to where I want to go? Pin
Richard MacCutchan21-Nov-23 22:37
mveRichard MacCutchan21-Nov-23 22:37 
QuestionSelectedIndexChanged for DropDown not fired when first item selected Pin
DalTXColtsFan17-Nov-23 8:41
DalTXColtsFan17-Nov-23 8:41 
AnswerRe: SelectedIndexChanged for DropDown not fired when first item selected Pin
Ron Nicholson17-Nov-23 8:57
professionalRon Nicholson17-Nov-23 8:57 
GeneralRe: SelectedIndexChanged for DropDown not fired when first item selected Pin
DalTXColtsFan17-Nov-23 9:03
DalTXColtsFan17-Nov-23 9:03 
GeneralRe: SelectedIndexChanged for DropDown not fired when first item selected Pin
Andre Oosthuizen18-Nov-23 8:27
mveAndre Oosthuizen18-Nov-23 8:27 
SuggestionRe: SelectedIndexChanged for DropDown not fired when first item selected Pin
Richard Deeming19-Nov-23 22:56
mveRichard Deeming19-Nov-23 22:56 
QuestionDumb it down for one who's basically a beginner Pin
DalTXColtsFan15-Nov-23 6:31
DalTXColtsFan15-Nov-23 6:31 
AnswerRe: Dumb it down for one who's basically a beginner Pin
Andre Oosthuizen15-Nov-23 8:25
mveAndre Oosthuizen15-Nov-23 8:25 
GeneralRe: Dumb it down for one who's basically a beginner Pin
DalTXColtsFan15-Nov-23 12:48
DalTXColtsFan15-Nov-23 12:48 
GeneralRe: Dumb it down for one who's basically a beginner Pin
Andre Oosthuizen16-Nov-23 6:36
mveAndre Oosthuizen16-Nov-23 6:36 
Questioncan't build blazor library in azure pipeline Pin
Super Lloyd6-Sep-23 18:08
Super Lloyd6-Sep-23 18:08 
AnswerRe: can't build blazor library in azure pipeline Pin
Super Lloyd6-Sep-23 19:27
Super Lloyd6-Sep-23 19:27 
QuestionBlazor component debugging Pin
Super Lloyd23-Aug-23 15:16
Super Lloyd23-Aug-23 15:16 
AnswerRe: Blazor component debugging Pin
Super Lloyd24-Aug-23 18:27
Super Lloyd24-Aug-23 18:27 
QuestionHTML SELECT CONTROL WITH RUNAT="SERVER Pin
tchia_k30-Jul-23 4:53
professionaltchia_k30-Jul-23 4:53 
AnswerRe: HTML SELECT CONTROL WITH RUNAT="SERVER Pin
Richard Deeming30-Jul-23 23:14
mveRichard Deeming30-Jul-23 23:14 
Question"Context.UserIdentifier" of SignalR is always null when I use CustomAuthenticationStateProvider in Blazor Server App Pin
Alex Wright 202221-Jul-23 4:45
Alex Wright 202221-Jul-23 4:45 
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<AuthenticationState> GetAuthenticationStateAsync()
        {
            try
            {
                var userSessionStorageResult = await _sessionStorage.GetAsync<UserSession>("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<Claim> {
                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<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

public class UserSession
{
    public int UserId { get; set; }
    public string Username { get; set; }
    public string UserRole { get; set; }
    public string Name { get; set; }
    public string TokenText { get; set; }
}


LoginController:

[Route("api/[controller]/[action]")]
    [ApiController]
    public class ApiLoginController : ControllerBase
    {
        private readonly SqliteContext _sqlServerContext;
        private readonly IConfiguration _configuration;
        private readonly IUserService _userService;

        public ApiLoginController(SqliteContext sqlServerContext, IConfiguration configuration, IUserService userService)
        {
            _sqlServerContext = sqlServerContext;
            _configuration = configuration;
            _userService = userService;
        }

        [HttpPost]
        public async 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);
        }

        private string 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;
        }

        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;
            }
        }
    }


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?

modified 21-Jul-23 9:51am.

SuggestionRe: "Context.UserIdentifier" of SignalR is always null when I use CustomAuthenticationStateProvider in Blazor Server App Pin
Richard Deeming24-Jul-23 0:17
mveRichard Deeming24-Jul-23 0:17 
QuestionIs is possible to import an excel file with hyperlinks? Pin
samflex16-Jul-23 18:25
samflex16-Jul-23 18:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.