public virtual async Task <AuthenticatedUser> Authenticate(string userNameOrEmail, string password)
        {
            using (_trace.Activity("Authenticate:" + userNameOrEmail))
            {
                var user = FindByUserNameOrEmail(userNameOrEmail);

                // Check if the user exists
                if (user == null)
                {
                    _trace.Information("No such user: "******"Password validation failed: " + userNameOrEmail);
                    return(null);
                }

                var passwordCredentials = user
                                          .Credentials
                                          .Where(c => c.Type.StartsWith(CredentialTypes.Password.Prefix, StringComparison.OrdinalIgnoreCase))
                                          .ToList();
                if (passwordCredentials.Count > 1 || !passwordCredentials.Any(c => String.Equals(c.Type, CredentialTypes.Password.Pbkdf2, StringComparison.OrdinalIgnoreCase)))
                {
                    await MigrateCredentials(user, passwordCredentials, password);
                }

                // Return the result
                _trace.Verbose("Successfully authenticated '" + user.Username + "' with '" + matched.Type + "' credential");
                return(new AuthenticatedUser(user, matched));
            }
        }
예제 #2
0
        public virtual async Task <PasswordAuthenticationResult> Authenticate(string userNameOrEmail, string password)
        {
            using (_trace.Activity("Authenticate"))
            {
                var user = FindByUserNameOrEmail(userNameOrEmail);

                // Check if the user exists
                if (user == null)
                {
                    _trace.Information("No such user.");

                    await Auditing.SaveAuditRecordAsync(
                        new FailedAuthenticatedOperationAuditRecord(
                            userNameOrEmail, AuditedAuthenticatedOperationAction.FailedLoginNoSuchUser));

                    return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.BadCredentials));
                }

                if (user is Organization)
                {
                    _trace.Information("Cannot authenticate organization account.");

                    await Auditing.SaveAuditRecordAsync(
                        new FailedAuthenticatedOperationAuditRecord(
                            userNameOrEmail, AuditedAuthenticatedOperationAction.FailedLoginUserIsOrganization));

                    return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.BadCredentials));
                }

                int remainingMinutes;

                if (IsAccountLocked(user, out remainingMinutes))
                {
                    _trace.Information($"Login failed. User account is locked for the next {remainingMinutes} minutes.");

                    return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.AccountLocked,
                                                            authenticatedUser: null, lockTimeRemainingMinutes: remainingMinutes));
                }

                // Validate the password
                Credential matched;
                if (!ValidatePasswordCredential(user.Credentials, password, out matched))
                {
                    _trace.Information("Password validation failed.");

                    await UpdateFailedLoginAttempt(user);

                    await Auditing.SaveAuditRecordAsync(
                        new FailedAuthenticatedOperationAuditRecord(
                            userNameOrEmail, AuditedAuthenticatedOperationAction.FailedLoginInvalidPassword));

                    return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.BadCredentials));
                }

                var passwordCredentials = user
                                          .Credentials
                                          .Where(c => c.IsPassword())
                                          .ToList();

                if (passwordCredentials.Count > 1 ||
                    !passwordCredentials.Any(c => string.Equals(c.Type, CredentialBuilder.LatestPasswordType, StringComparison.OrdinalIgnoreCase)))
                {
                    await MigrateCredentials(user, passwordCredentials, password);
                }

                // Reset failed login count upon successful login
                await UpdateSuccessfulLoginAttempt(user);

                // Return the result
                _trace.Verbose("User successfully authenticated with '" + matched.Type + "' credential");
                return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, new AuthenticatedUser(user, matched)));
            }
        }
예제 #3
0
        public virtual async Task <PasswordAuthenticationResult> Authenticate(string userNameOrEmail, string password)
        {
            using (_trace.Activity("Authenticate:" + userNameOrEmail))
            {
                var user = FindByUserNameOrEmail(userNameOrEmail);

                // Check if the user exists
                if (user == null)
                {
                    var ldapUser = this.Ldap.ValidateUsernameAndPassword(userNameOrEmail, password);

                    if (ldapUser != null)
                    {
                        _trace.Information($"Creating user from LDAP credentials: {userNameOrEmail}");
                        var ldapCredential = _credentialBuilder.CreateExternalCredential(AuthenticationTypes.LdapUser, ldapUser.Username, ldapUser.Identity);

                        var authUser = await this.Register(ldapUser.Username, ldapUser.Email, ldapCredential);

                        return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, authUser));
                    }

                    _trace.Information("No such user: "******"Login failed. User account {userNameOrEmail} is locked for the next {remainingMinutes} minutes.");

                    return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.AccountLocked,
                                                            authenticatedUser: null, lockTimeRemainingMinutes: remainingMinutes));
                }

                // Validate the password
                Credential matched;
                if (!ValidatePasswordCredential(user.Credentials, password, out matched))
                {
                    var isValid = this.Ldap.ValidateCredentials(user.Credentials, password, out matched);
                    if (isValid)
                    {
                        _trace.Verbose($"Successfully authenticated '{user.Username}' with '{matched.Type}' credential");
                        return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, new AuthenticatedUser(user, matched)));
                    }

                    _trace.Information($"Password validation failed: {userNameOrEmail}");

                    await UpdateFailedLoginAttempt(user);

                    await Auditing.SaveAuditRecordAsync(
                        new FailedAuthenticatedOperationAuditRecord(
                            userNameOrEmail, AuditedAuthenticatedOperationAction.FailedLoginInvalidPassword));

                    return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.BadCredentials));
                }

                var passwordCredentials = user
                                          .Credentials
                                          .Where(c => CredentialTypes.IsPassword(c.Type))
                                          .ToList();

                if (passwordCredentials.Count > 1 ||
                    !passwordCredentials.Any(c => string.Equals(c.Type, CredentialBuilder.LatestPasswordType, StringComparison.OrdinalIgnoreCase)))
                {
                    await MigrateCredentials(user, passwordCredentials, password);
                }

                // Reset failed login count upon successful login
                await UpdateSuccessfulLoginAttempt(user);

                // Return the result
                _trace.Verbose("Successfully authenticated '" + user.Username + "' with '" + matched.Type + "' credential");
                return(new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, new AuthenticatedUser(user, matched)));
            }
        }