public SignUpResult SignUp(string name, string credentialTypeCode, string identifier, string secret) { Users user = new Users(); user.Name = name; user.Created = DateTime.Now.ToShortDateString(); this._context.Users.Add(user); this._context.SaveChanges(); CredentialTypes credentialType = this._context.CredentialTypes.FirstOrDefault(ct => string.Equals(ct.Code, credentialTypeCode, StringComparison.OrdinalIgnoreCase)); if (credentialType == null) { return(new SignUpResult(success: false, error: SignUpResultError.CredentialTypeNotFound)); } Credentials credential = new Credentials(); credential.UserId = user.Id; credential.CredentialTypeId = credentialType.Id; credential.Identifier = identifier; if (!string.IsNullOrEmpty(secret)) { byte[] salt = Pbkdf2Hasher.GenerateRandomSalt(); string hash = Pbkdf2Hasher.ComputeHash(secret, salt); credential.Secret = hash; credential.Extra = Convert.ToBase64String(salt); } this._context.Credentials.Add(credential); this._context.SaveChanges(); return(new SignUpResult(user: user, success: true)); }
/// <summary> /// On subscribe, set API keys with push capability to expire in <see cref="PushKeysExpirationInDays" /> days. /// </summary> /// <param name="context"></param> public async Task OnSubscribeAsync(UserSecurityPolicySubscriptionContext context) { var pushKeys = context.User.Credentials.Where(c => CredentialTypes.IsApiKey(c.Type) && ( c.Scopes.Count == 0 || c.Scopes.Any(s => s.AllowedAction.Equals(NuGetScopes.PackagePush, StringComparison.OrdinalIgnoreCase) || s.AllowedAction.Equals(NuGetScopes.PackagePushVersion, StringComparison.OrdinalIgnoreCase) )) ); var expires = DateTime.UtcNow.AddDays(PushKeysExpirationInDays); var expireTasks = new List <Task>(); foreach (var key in pushKeys) { if (!key.Expires.HasValue || key.Expires > expires) { expireTasks.Add(_auditing.SaveAuditRecordAsync( new UserAuditRecord(context.User, AuditedUserAction.ExpireCredential, key))); key.Expires = expires; } } await Task.WhenAll(expireTasks); _diagnostics.Information($"Expiring {pushKeys.Count()} keys with push capability for user '{context.User.Username}'."); }
public ValidateResult Validate(string credentialTypeCode, string identifier, string secret) { CredentialTypes credentialType = this._context.CredentialTypes.FirstOrDefault(ct => string.Equals(ct.Code, credentialTypeCode, StringComparison.OrdinalIgnoreCase)); if (credentialType == null) { return(new ValidateResult(success: false, error: ValidateResultError.CredentialTypeNotFound)); } Credentials credential = this._context.Credentials.FirstOrDefault(c => c.CredentialTypeId == credentialType.Id && c.Identifier == identifier); if (credential == null) { return(new ValidateResult(success: false, error: ValidateResultError.CredentialNotFound)); } if (!string.IsNullOrEmpty(secret)) { byte[] salt = Convert.FromBase64String(credential.Extra); string hash = Pbkdf2Hasher.ComputeHash(secret, salt); if (credential.Secret != hash) { return(new ValidateResult(success: false, error: ValidateResultError.SecretNotValid)); } } return(new ValidateResult(user: this._context.Users.Find(credential.UserId), success: true)); }
public ChangeSecretResult ChangeSecret(string credentialTypeCode, string identifier, string secret) { CredentialTypes credentialType = this._context.CredentialTypes.FirstOrDefault(ct => string.Equals(ct.Code, credentialTypeCode, StringComparison.OrdinalIgnoreCase)); if (credentialType == null) { return(new ChangeSecretResult(success: false, error: ChangeSecretResultError.CredentialTypeNotFound)); } Credentials credential = this._context.Credentials.FirstOrDefault(c => c.CredentialTypeId == credentialType.Id && c.Identifier == identifier); if (credential == null) { return(new ChangeSecretResult(success: false, error: ChangeSecretResultError.CredentialNotFound)); } byte[] salt = Pbkdf2Hasher.GenerateRandomSalt(); string hash = Pbkdf2Hasher.ComputeHash(secret, salt); credential.Secret = hash; credential.Extra = Convert.ToBase64String(salt); this._context.Credentials.Update(credential); this._context.SaveChanges(); return(new ChangeSecretResult(success: true)); }
public CredentialAuditRecord(Credential credential, bool removed) { if (credential == null) { throw new ArgumentNullException(nameof(credential)); } Key = credential.Key; Type = credential.Type; Description = credential.Description; Identity = credential.Identity; // Track the value for credentials that are definitely revocable (API Key, etc.) and have been removed if (removed && !CredentialTypes.IsPassword(credential.Type)) { Value = credential.Value; } Created = credential.Created; Expires = credential.Expires; LastUsed = credential.LastUsed; // Track scopes Scopes = new List <ScopeAuditRecord>(); foreach (var scope in credential.Scopes) { Scopes.Add(new ScopeAuditRecord(scope.Subject, scope.AllowedAction)); } }
public CredentialState GetCredentialState(BiometricIdentity identity, CredentialTypes credentialType) { if (identity == null) { throw new ArgumentNullException(nameof(identity)); } return(WinBiometric.GetCredentialState(identity, credentialType)); }
public CredentialAuditRecord(Credential credential, bool removed) { Type = credential.Type; Identity = credential.Ident; // Track the value for credentials that are definitely revokable (API Key, etc.) and have been removed if (removed && !CredentialTypes.IsPassword(credential.Type)) { Value = credential.Value; } }
private static CredentialKind GetCredentialKind(string type) { if (CredentialTypes.IsApiKey(type)) { return(CredentialKind.Token); } else if (CredentialTypes.IsPassword(type)) { return(CredentialKind.Password); } return(CredentialKind.External); }
public CredentialAuditRecord(Credential credential, bool removed) { Key = credential.Key; Type = credential.Type; Identity = credential.Identity; // Track the value for credentials that are definitely revocable (API Key, etc.) and have been removed if (removed && !CredentialTypes.IsPassword(credential.Type)) { Value = credential.Value; } Created = credential.Created; Expires = credential.Expires; LastUsed = credential.LastUsed; }
private bool IsRevocable(ApiKeyViewModel apiKeyViewModel) { if (apiKeyViewModel == null) { return(false); } if (apiKeyViewModel.HasExpired) { return(false); } if (!CredentialTypes.IsApiKey(apiKeyViewModel.Type)) { return(false); } return(true); }
// Returns the set of credential types supported by this store for the specified principal. // Used when an application tries to access the PasswordInfo property of a newly-inserted // (not yet persisted) AuthenticablePrincipal, to determine whether it should be allowed. // Also used to implement AuthenticablePrincipal.SupportedCredentialTypes. internal override CredentialTypes SupportedCredTypes(AuthenticablePrincipal p) { // Fake principals do not have store objects, so they certainly don't have stored creds. if (p.fakePrincipal) { return((CredentialTypes)0); } CredentialTypes supportedTypes = CredentialTypes.Password; // Longhorn SAM supports certificate-based authentication if (this.IsLSAM) { supportedTypes |= CredentialTypes.Certificate; } return(supportedTypes); }
public bool IsActiveApiKeyCredential(Credential credential) { if (credential == null) { return(false); } if (!CredentialTypes.IsApiKey(credential.Type)) { return(false); } if (IsCredentialExpiredOrNonScopedApiKeyNotUsedInLastDays(credential)) { return(false); } if (credential.RevocationSourceKey != null) { return(false); } return(true); }
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) { _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)) { _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))); } }
private async Task <AuthenticatedUser> AuthenticateInternal(Func <Credential, Credential> matchCredential, Credential credential) { if (credential.Type.StartsWith(CredentialTypes.Password.Prefix, StringComparison.OrdinalIgnoreCase)) { // Password credentials cannot be used this way. throw new ArgumentException(Strings.PasswordCredentialsCannotBeUsedHere, nameof(credential)); } using (_trace.Activity("Authenticate Credential: " + credential.Type)) { var matched = matchCredential(credential); if (matched == null) { _trace.Information("No user matches credential of type: " + credential.Type); await Auditing.SaveAuditRecordAsync( new FailedAuthenticatedOperationAuditRecord(null, AuditedAuthenticatedOperationAction.FailedLoginNoSuchUser, attemptedCredential : credential)); return(null); } if (matched.User is Organization) { _trace.Information($"Cannot authenticate organization account '{matched.User.Username}'."); await Auditing.SaveAuditRecordAsync( new FailedAuthenticatedOperationAuditRecord(null, AuditedAuthenticatedOperationAction.FailedLoginUserIsOrganization, attemptedCredential : credential)); return(null); } if (matched.HasExpired) { _trace.Verbose("Credential of type '" + matched.Type + "' for user '" + matched.User.Username + "' has expired on " + matched.Expires.Value.ToString("O", CultureInfo.InvariantCulture)); return(null); } if (CredentialTypes.IsApiKey(matched.Type) && !matched.IsScopedApiKey() && !matched.HasBeenUsedInLastDays(_config.ExpirationInDaysForApiKeyV1)) { // API key credential was last used a long, long time ago - expire it await Auditing.SaveAuditRecordAsync( new UserAuditRecord(matched.User, AuditedUserAction.ExpireCredential, matched)); matched.Expires = _dateTimeProvider.UtcNow; await Entities.SaveChangesAsync(); _trace.Verbose( "Credential of type '" + matched.Type + "' for user '" + matched.User.Username + "' was last used on " + matched.LastUsed.Value.ToString("O", CultureInfo.InvariantCulture) + " and has now expired."); return(null); } // update last used timestamp matched.LastUsed = _dateTimeProvider.UtcNow; await Entities.SaveChangesAsync(); _trace.Verbose("Successfully authenticated '" + matched.User.Username + "' with '" + matched.Type + "' credential"); return(new AuthenticatedUser(matched.User, matched)); } }
public RequestData(string credential, CredentialTypes type, T data) { CredentialID = credential; CredentialType = type; Data = data; }
public void SetCredential(CredentialTypes credentialType, byte[] credential, CredentialFormat format) { WinBiometric.SetCredential(credentialType, credential, format); }
public void RemoveCredential(BiometricIdentity identity, CredentialTypes credentialType) { WinBiometric.RemoveCredential(identity, credentialType); }