Beispiel #1
0
        public void ImplementStrategy(string accountId, string newPasswordPlain)
        {
            Account account = null;

            try
            {
                //Get account from db
                account = _accountRepo.Find(a => a.AccountId == accountId).SingleOrDefault();

                //Password
                string salt       = _passwordSaltGenerator.Generate();
                string passHashed = _passwordHashHelper.GenerateHash(salt + newPasswordPlain);

                //Update account data
                UpdateDefinition <Account> updDef = Builders <Account> .Update
                                                    .Set(x => x.PasswordStatus, PasswordStatus.Set)
                                                    .Set(x => x.PasswordLastChanged, DateTime.Now)
                                                    .Set(x => x.Salt, salt)
                                                    .Set(x => x.Password, passHashed);

                _accountRepo.UpdateOne(x => x.AccountId == accountId, updDef);
            }
            catch (Exception ex)
            {
                //Log error
                _logger.LogError("UserAssignedPasswordSetStrategy.ImplementStrategy", "Exception was thrown", new
                {
                    AccountId = accountId,
                    Account   = account,
                    Exception = ex
                });
                throw;
            }
        }
        public async Task <TokenResult> Execute(string refreshToken)
        {
            try
            {
                //1.Validate and extract refresh token
                if (!_refreshTokenExtracter.TryExractToken(refreshToken, out List <Claim> refreshTokenClaims))
                {
                    throw new InvalidTokenException("Jwt token is corrupted or expired");
                }

                string rTokenJti = refreshTokenClaims.Single(c => c.Type == JwtRegisteredClaimNames.Jti).Value;

                //2.Check if refresh token is revoked. If it is throw a security exception
                if (await _revokedTokenRepo.Exists(rTokenJti))
                {
                    throw new TokenRevokedException($"Token {rTokenJti} already revoked");
                }

                //3.Generate short token
                var key   = _symmetricKeyProvider.GetKey();
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                //Create stoken claims using some claims from parent rtoken
                var shortTokenClaims = refreshTokenClaims.Where(c => c.Type == ClaimTypes.Name || c.Type == ClaimTypes.Role).Select(c => new Claim(c.Type, c.Value)).ToList();
                //Add token Jti claim
                string jti = _tokenIdGenerator.Generate();
                shortTokenClaims.Add(new Claim(JwtRegisteredClaimNames.Jti, jti));
                //Add RefreshTokenId of the rtoken to the stoken claims as RefreshTokenId claim
                shortTokenClaims.Add(new Claim("rtokenjti", rTokenJti));

                JwtSecurityToken jwtTokenOptions = new JwtSecurityToken(
                    issuer: _shortTokenConfig.ValidIssuer,
                    audience: _shortTokenConfig.ValidAudience,
                    claims: shortTokenClaims,
                    expires: DateTime.Now.AddMinutes(_shortTokenConfig.ExpiresInMin),
                    signingCredentials: creds
                    );

                string shortToken = new JwtSecurityTokenHandler().WriteToken(jwtTokenOptions);

                return(new TokenResult(null, shortToken, jwtTokenOptions.ValidTo));
            }
            catch (Exception ex)
            {
                //Log error
                _logger.LogError("GenerateShortTokenCommand.Execute", "Exception was thrown", new
                {
                    Exception = ex
                });

                throw;
            }
        }
Beispiel #3
0
        public async Task ImplementConfirmation(string accountId)
        {
            Account account = null;

            try
            {
                // Get account from db.
                account = _accountRepo.Find(a => a.AccountId == accountId).SingleOrDefault();

                // Generate confirmation code and it's hash
                string emailConfirmCodePlain = _emailConfirmCodeGenerator.Generate();
                string emailConirmCodeHashed = _hashHelper.GenerateHash(emailConfirmCodePlain);

                // Will be saved in db.
                ConfirmEmailRequest confirmEmailRequest = new ConfirmEmailRequest()
                {
                    Id         = Guid.NewGuid().ToString("n"),
                    AccountId  = account.AccountId,
                    Code       = emailConirmCodeHashed,
                    Email      = account.Email,
                    CreateDate = DateTime.Now,
                    Status     = ConfirmEmailRequestStatus.NotResolved
                };
                _requestRepo.InsertOne(confirmEmailRequest);

                // Will be sent to user's email.
                EmailConfirmationByLinkRequestEvent confMail = new EmailConfirmationByLinkRequestEvent()
                {
                    CorrelationId = Guid.NewGuid().ToString(),
                    Issuer        = "AuthServer.UserSystem.Services.Strategies.ConfirmLinkEmailConfirmationStrategy",
                    IssuerSystem  = "AuthServer.UserSystem",
                    EventDate     = DateTime.Now,

                    Username        = account.Username,
                    Email           = account.Email,
                    ConfirmationUrl = string.Format(_confirmLinkUrl, emailConfirmCodePlain)
                };
                await Publish(confMail);
            }
            catch (Exception ex)
            {
                // Log error.
                _logger.LogError("ConfirmLinkEmailConfirmationStrategy.ImplementConfirmation", "Exception was thrown.", new
                {
                    Account   = account,
                    Exception = ex
                });
                throw;
            }
        }
        public void ImplementStrategy(string accountId, string newPasswordPlain)
        {
            Account account = null;

            try
            {
                // Get account from db.
                account = _accountRepo.Find(a => a.AccountId == accountId).SingleOrDefault();
                if (account.EmailStatus != EmailStatus.Confirmed)
                {
                    return;
                }

                // Prepare the password.
                string passwordPlain = _passwordGenerator.Generate();
                string salt          = _passwordSaltGenerator.Generate();
                string passHashed    = _passwordHashHelper.GenerateHash(account.Salt + passwordPlain);

                // Update account data.
                UpdateDefinition <Account> updDef = Builders <Account> .Update
                                                    .Set(x => x.PasswordStatus, PasswordStatus.Set)
                                                    .Set(x => x.PasswordLastChanged, DateTime.Now)
                                                    .Set(x => x.Salt, salt)
                                                    .Set(x => x.Password, passHashed);

                _accountRepo.UpdateOne(x => x.AccountId == accountId, updDef);

                // Publish event that may be used, for example, to email the password to the user.
                Publish(new DirectPasswordSetEvent()
                {
                    Email         = account.Email,
                    Username      = account.Username,
                    PasswordPlain = passwordPlain
                });
            }
            catch (Exception ex)
            {
                // Log error.
                _logger.LogError("DirectPasswordSetStrategy.ImplementStrategy", "Exception was thrown", new
                {
                    AccountId = accountId,
                    Account   = account,
                    Exception = ex
                });
                throw;
            }
        }
        public async Task Execute(string accountId, PasswordChangeModel model, IValidator validator)
        {
            try
            {
                //Validate input
                _validationStrategy.Validate(model, validator);
                if (validator.HasErrors)
                {
                    return;
                }

                //Validate old password and find account
                Account account = await _accountRepo.Find(x => x.AccountId == accountId && x.AccountStatus != AccountStatus.Inactive).SingleOrDefaultAsync();

                if (account == null ||
                    account.PasswordStatus == PasswordStatus.Empty ||
                    !_secretHashHelper.ValidateSecret(account.Salt + model.OldPassword, account.Password))
                {
                    validator.AddError("Wrong old password", "OldPassword");
                    return;
                }

                //Generate new salt
                string newSalt = _passwordSaltGenerator.Generate();

                //Generate new hashed password
                string newHashedPass = _secretHashHelper.GenerateHash(newSalt + model.NewPassword);

                //Save in db
                _accountRepo.UpdateOne(x => x.AccountId == accountId, CreateUpdateDef(newHashedPass, newSalt));

                //Raise a PasswordChanged event
                PasswordChangedEvent passwordChangedEvent = CreatePasswordChangedEvent(account);
                await Publish(passwordChangedEvent);

                return;
            }
            catch (Exception ex)
            {
                await _logger.LogErrorAsync("ChangeAccountPasswordCommand.Execute", "Exception occurred", new
                {
                    Exception = ex
                });

                throw;
            }
        }
Beispiel #6
0
 public static string GenerateString(this ISecretGenerator generator, int length = 128)
 {
     byte[] randomData = generator.Generate((length / 4 * 3) + 1);
     return(Convert.ToBase64String(randomData).Substring(0, length).Replace('/', '-').Replace('+', '_'));
 }
Beispiel #7
0
        public async Task <TokenResult> Execute(string accountId, List <Claim> claims, TokenAdditionalData additionalData, DateTime?customExpireDate = null)
        {
            try
            {
                SymmetricSecurityKey key   = _symmetricKeyProvider.GetKey();
                SigningCredentials   creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                //Generate and add token Jti claim. Will be used in short tokens to identify the creator refresh token
                string tokenJti = _tokenIdGenerator.Generate();
                claims.Add(new Claim(JwtRegisteredClaimNames.Jti, tokenJti));

                //Set expire date
                DateTime expireDate;
                if (customExpireDate != null)
                {
                    expireDate = customExpireDate.Value;
                }
                else
                {
                    expireDate = DateTime.Now.AddMinutes(_rTokenConfig.ExpiresInMin);
                }

                JwtSecurityToken jwtTokenOptions = new JwtSecurityToken(
                    issuer: _rTokenConfig.ValidIssuer,
                    audience: _rTokenConfig.ValidAudience,
                    claims: claims,
                    expires: expireDate,
                    signingCredentials: creds
                    );

                //Generate token string
                string token = new JwtSecurityTokenHandler().WriteToken(jwtTokenOptions);

                //Create token db record
                AccountRTokenInfo accountRTokenInfo = new AccountRTokenInfo()
                {
                    TokenId       = tokenJti,
                    AccountId     = accountId,
                    ExpireDate    = expireDate,
                    Status        = AccountRTokenStatus.Active,
                    CreateDate    = DateTime.Now,
                    DeviceInfo    = additionalData.DeviceInfo,
                    RequesterIPv4 = additionalData.RequesterIPv4,
                    RequesterIPv6 = additionalData.RequesterIPv6
                };

                //Save token db record
                await _accountRTokenRepo.InsertOneAsync(accountRTokenInfo);

                return(new TokenResult(tokenJti, token, jwtTokenOptions.ValidTo));
            }
            catch (Exception ex)
            {
                //Log error
                _logger.LogError("GenerateRefreshTokenCommand.Execute", "Exception was thrown", new
                {
                    Exception = ex
                });

                throw;
            }
        }