public async Task <Response> EnableAuthenticator(EnableAuthenticatorRequest request, string userId) { _logger.LogInformation("Enabled authenticator for {userId}", userId); var user = await _userManager.FindByIdAsync(userId); if (user.TwoFactorEnabled) { return(Response.ForError("2FA already enabled.")); } if (request.Code.IsNullOrEmpty()) { return(Response.ForError("Code is missing.")); } var verificationCode = CleanCode(request.Code); var is2FaTokenValid = await _userManager.VerifyTwoFactorTokenAsync(user, _userManager.Options.Tokens.AuthenticatorTokenProvider, verificationCode); if (!is2FaTokenValid) { return(Response.ForError("2FA token is not valid.")); } var result = await _userManager.SetTwoFactorEnabledAsync(user, true); if (!result.Succeeded) { return(Response.ForErrors(result.Errors.Select(c => $"{c.Code} - {c.Description}"))); } return(Response.ForSuccess()); }
public async Task <Response <TIdentity> > CheckCredentials(string username, string password) { _logger.LogInformation("Check credentials for {username}", username); var user = await _userManager.FindByNameAsync(username); if (user == null) { return(Response.ForError("Invalid credentials.")); } Response lockout; if ((lockout = await GetLockedStatus(user)) != null) { return(lockout); } if (await _userManager.CheckPasswordAsync(user, password)) { await _userManager.ResetAccessFailedCountAsync(user); _logger.LogInformation("Credentials valid for {username}, access failed count is reset.", username); return(Response <TIdentity> .ForSuccess(user)); } await _userManager.AccessFailedAsync(user); if ((lockout = await GetLockedStatus(user)) != null) { return(lockout); } return(Response.ForError("Invalid credentials.")); }
public async Task <Response <AuthenticatorKey> > GetAuthenticatorKey(string userId) { _logger.LogInformation("Get authentication key {userId}", userId); var user = await _userManager.FindByIdAsync(userId); if (user == null) { _logger.LogInformation("User {userId} not found", userId); return(Response.ForError("Credentials are not valid.")); } if (user.TwoFactorEnabled) { return(Response.ForError("2FA already enabled.")); } var unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user); if (string.IsNullOrEmpty(unformattedKey)) { await _userManager.ResetAuthenticatorKeyAsync(user); unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user); } return(Response <AuthenticatorKey> .ForSuccess(new AuthenticatorKey { SharedKey = FormatKey(unformattedKey), AuthenticatorUri = GenerateQrCodeUri(user.Email, unformattedKey) })); }
public async Task <Response <TIdentity> > Verify(string code, string username, string password) { _logger.LogInformation("Verify {code}", code); if (code.IsNullOrEmpty()) { return(Response.ForError("Code is missing.")); } var user = await _userManager.FindByNameAsync(username); if (user == null) { _logger.LogInformation("User {username} not found", username); return(Response.ForError("Credentials are not valid.")); } if (!await _userManager.CheckPasswordAsync(user, password)) { return(Response.ForError("Credentials are not valid.")); } var authenticatorCode = CleanCode(code); _logger.LogInformation("Cleaned {authenticatorCode}", authenticatorCode); // it's ok to log this, as this info is transient var is2FaTokenValid = await _userManager.VerifyTwoFactorTokenAsync(user, _userManager.Options.Tokens.AuthenticatorTokenProvider, authenticatorCode); if (!is2FaTokenValid) { return(Response.ForError("2FA token is not valid.")); } return(Response <TIdentity> .ForSuccess()); }
public async Task <Response <AuthorizationCodeTokenResponse> > GetAccessToken(Requests.AuthorizationCodeTokenRequest request) { var authority = _idpOptions.Enable ? _idpOptions.AuthorityUrl : _partyDetailsOptions.BaseUri; using (var requestBody = new FormUrlEncodedContent(new Dictionary <string, string> { { "grant_type", "authorization_code" }, { "scope", "iSHARE" }, { "client_id", _spaOptions.SpaClientId }, { "client_secret", _spaOptions.SpaClientSecret }, { "redirect_uri", Path.Combine(_spaOptions.BaseUri, "callback") }, { "code", request.Code } })) { var tokenResponse = await authority.AppendPathSegment("connect/token") .PostAsync(requestBody) ; if (tokenResponse.StatusCode == HttpStatusCode.OK) { var content = await Task.FromResult(tokenResponse).ReceiveJson(); return(Response <AuthorizationCodeTokenResponse> .ForSuccess( new AuthorizationCodeTokenResponse { AccessToken = (string)content.access_token, ExpiresIn = (int)content.expires_in })); } } return(Response.ForError("Token retrieval failed")); }
private async Task <Response> GetLockedStatus(TIdentity user) { if (!await _userManager.IsLockedOutAsync(user)) { return(null); } _logger.LogInformation("Username {username} is locked out", user.UserName); return(Response.ForError("Your account has been locked out due to multiple failed login attempts.")); }
public async Task <Response> Logout() { string token = _httpContext.HttpContext.Request.Headers["Authorization"]; var authority = _idpOptions.Enable ? _idpOptions.AuthorityUrl : _partyDetailsOptions.BaseUri; if (!string.IsNullOrEmpty(token) && token.StartsWith("Bearer ")) { var result = await _httpClient.RevokeTokenAsync(new TokenRevocationRequest { Address = Path.Combine(authority, "connect/revocation"), ClientId = _spaOptions.SpaClientId, ClientSecret = _spaOptions.SpaClientSecret, Token = token.Substring("Bearer ".Length).Trim() }); } return(Response.ForSuccess()); }
public async Task <Response <TIdentity> > Login(LoginRequest request) { _logger.LogInformation("Login for {username}", request?.Username); if (request == null) { return(Response.ForError(LoginErrorMessages.InvalidCredentials)); } var result = await CheckCredentials(request.Username, request.Password); if (!result.Success) { return(Response.ForError(result.Errors.FirstOrDefault())); } if (!_spaOptions.TwoFactorEnabled.HasValue || !_spaOptions.TwoFactorEnabled.Value) { return(Response <TIdentity> .ForSuccess(result.Model)); } if (result.Model.TwoFactorEnabled) { if (request.TwoFactorCode.IsNullOrEmpty()) { return(Response.ForError(LoginErrorMessages.TwoFactorCodeRequired)); } var result2Fa = await Verify(request.TwoFactorCode, request.Username, request.Password); if (!result2Fa.Success) { return(Response.ForError(LoginErrorMessages.InvalidCredentials)); } } else { return(Response.ForError(LoginErrorMessages.TwoFactorSetupRequired)); } return(Response <TIdentity> .ForSuccess(result.Model)); }