Esempio n. 1
0
        public async Task <JwtRefreshDTO> AllowLogin(string username, string password)
        {
            var helperShared = new YetAnotherPrivateChat.Shared.HelperShared.Helper();

            var user = await ctx.Users.FirstOrDefaultAsync(c => c.Username == username);

            var allowed = helperShared.ComparePassword(user.Password, password);

            if (!allowed)
            {
                throw new Exception("Denied login, please check your password and username");
            }

            int expiration = 6;

            /*
             * What is the rationale of adding the row id to the Refresh token?
             * Since we need to check if the Refresh Token is still valid or not we need some identification.
             * I could send a blank Refresh token and save its string to the DB, but them I would have all of the Refresh tokens stored
             * If a breach happened the attacker would have access of all the users, but now since I'm not storing anything the attacker would also need the secret key
             * So I'm pretty much adding another chain to protect the application.
             */

            var refreshTokenDb = new RefreshTokenDb(user.UserId, expiration);

            var result = _context.RefreshDb.Add(refreshTokenDb);
            await _context.SaveChangesAsync();

            var refreshToken = new RefreshToken(expiration, result.Entity.RefreshTokenDbId);
            var jwt          = new JwtToken(user.UserId, user.RegistrationDate, user.Admin);

            return(new JwtRefreshDTO(refreshToken, jwt));
        }
        public static RefreshToken Map(this RefreshTokenDb refreshToken)
        {
            if (refreshToken is null)
            {
                return(null);
            }

            return(new()
            {
                Id = refreshToken.Id,
                Token = refreshToken.Token,
                Expires = refreshToken.Expires,
                Created = refreshToken.Created,
                CreatedByIp = refreshToken.CreatedByIp,
                Revoked = refreshToken.Revoked,
                RevokedByIp = refreshToken.RevokedByIp,
                ReplacedByToken = refreshToken.ReplacedByToken,
                ReasonRevoked = refreshToken.ReasonRevoked
            });
        }
Esempio n. 3
0
        public async Task <RefreshToken> RefreshRefreshToken(int userId, int tokenId)
        {
            /*
             * If the Refresh token is already older than one month, a new one is created.
             * Why? I think is a good idea to rotate those keys.
             * Why one month? IDK, probably should be less than one month, just trying to avoid some DB trip.
             * Keep in mind that the token is still valid for 6 month, by default, so no problem if the user logs before one month.
             * Older Refresh Token became invalid.
             */
            int expiration = 6;

            var refreshTokenDb = new RefreshTokenDb(userId, expiration);

            var result = _context.RefreshDb.Add(refreshTokenDb);
            await _context.SaveChangesAsync();

            var refreshToken = new RefreshToken(expiration, result.Entity.RefreshTokenDbId);

            await DisableRefreshToken(tokenId);

            return(refreshToken);
        }
Esempio n. 4
0
        private async Task <AuthenticationResult> GenerateAuthenticationResult(IdentityUser newUser)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key          = Encoding.ASCII.GetBytes(_jwtSettings.Secret);


            var claims = new List <Claim>
            {
                new Claim(JwtRegisteredClaimNames.Sub, newUser.Email),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Email, newUser.Email),
                new Claim("id", newUser.Id)
            };


            var userClaims = await _userManager.GetClaimsAsync(newUser);

            claims.AddRange(userClaims);

            var userRoles = await _userManager.GetRolesAsync(newUser);

            foreach (var userRole in userRoles)
            {
                claims.Add(new Claim(ClaimTypes.Role, userRole));
                var role = await _userManager.FindByNameAsync(userRole);

                if (role == null)
                {
                    continue;
                }
                var roleClaims = await _userManager.GetClaimsAsync(role);

                foreach (var roleClaim in roleClaims)
                {
                    if (claims.Contains(roleClaim))
                    {
                        continue;
                    }

                    claims.Add(roleClaim);
                }
            }

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject            = new ClaimsIdentity(claims),
                Expires            = DateTime.Now.Add(_jwtSettings.TokenLifeTime),
                SigningCredentials =
                    new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };

            var token        = tokenHandler.CreateToken(tokenDescriptor);
            var refreshToken = new RefreshTokenDb
            {
                JwtId        = token.Id,
                UserId       = newUser.Id,
                CreationDate = DateTime.UtcNow,
                ExpiryDate   = DateTime.UtcNow.AddDays(30)
            };

            await _dbContext.RefreshTokens.AddAsync(refreshToken);

            await _dbContext.SaveChangesAsync();

            return(new AuthenticationResult
            {
                Success = true,
                Token = tokenHandler.WriteToken(token),
                RefreshToken = refreshToken.Token
            });
        }