public async Task <IActionResult> Login(LoginInputModel model, string button) { var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); _logger.LogInformation("displaying login options"); // the user clicked the "cancel" button if (button != "login") { if (context != null) { // if the user cancels, send a result back into IdentityServer as if they // denied the consent (even if this client does not require consent). // this will send back an access denied OIDC error response to the client. await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied); // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null if (await _clientStore.IsPkceClientAsync(context.Client.ClientId)) { // if the client is PKCE then we assume it's native, so this change in how to // return the response is for better UX for the end user. return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } return(Redirect(model.ReturnUrl)); } else { // since we don't have a valid context, then we just go back to the home page return(Redirect("~/")); } } if (ModelState.IsValid) { ResourceOwnerPasswordValidationContext ValidationContext = new ResourceOwnerPasswordValidationContext { UserName = model.Username, Password = model.Password, }; _logger.LogInformation("Setting up validation context for user"); var passwordValidator = _resourceOwnerPasswordValidation as ResourceOwnerPasswordValidator; ValidationContext = await passwordValidator.ValidatePassword(ValidationContext); _logger.LogInformation("Validation process started"); // validate username/password against in-memory store if (ValidationContext.Result != null) { if (ValidationContext.Result.Subject != null) { if (ValidationContext.Result.Subject.Identity.IsAuthenticated) { _logger.LogInformation("Validation process succesfully retrieved authenticated user"); var user = _userRepository.FindUserByUsernameOrEmail(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(model.Username, ValidationContext.Result.Subject.ToString(), model.Username)); // only set explicit expiration here if user chooses "remember me". // otherwise we rely upon expiration configured in cookie middleware. AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; var claims = ProfileService.GetUserClaims(user); // issue authentication cookie with subject ID and username _logger.LogInformation("Issuing authentication cookie"); var isuser = new IdentityServerUser(user.UsersId.ToString()) { DisplayName = user.Username }; await HttpContext.SignInAsync(isuser, props); if (context != null) { if (await _clientStore.IsPkceClientAsync(context.Client.ClientId)) { // if the client is PKCE then we assume it's native, so this change in how to // return the response is for better UX for the end user. return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null return(Redirect(model.ReturnUrl)); } // request for a local page if (Url.IsLocalUrl(model.ReturnUrl)) { return(Redirect(model.ReturnUrl)); } else if (string.IsNullOrEmpty(model.ReturnUrl)) { return(Redirect("~/")); } else { // user might have clicked on a malicious link - should be logged throw new Exception("invalid return URL"); } } } } await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError(string.Empty, ValidationContext.Result.ErrorDescription); } // something went wrong, show form with error var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }
public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { // 默认手机号登录、支持邮箱登录 await ReplaceEmailToUsernameOfInputIfNeeds(context); var user = await UserManager.FindByNameAsync(context.UserName); string errorDescription; if (user != null) { var result = await SignInManager.CheckPasswordSignInAsync(user, context.Password, true); if (result.Succeeded) { var sub = await UserManager.GetUserIdAsync(user); Logger.LogInformation("Credentials validated for username: {username}", context.UserName); await Events.RaiseAsync(new UserLoginSuccessEvent (context.UserName, sub, context.UserName, interactive : false)); var additionalClaims = new List <Claim> (); await AddCustomClaimsAsync(additionalClaims, user, context); context.Result = new GrantValidationResult( sub, OidcConstants.AuthenticationMethods.Password, additionalClaims.ToArray() ); return; } else if (result.IsLockedOut) { Logger.LogInformation("Authentication failed for username: {username}, reason: locked out", context.UserName); await Events.RaiseAsync(new UserLoginFailureEvent (context.UserName, "locked out", interactive : false)); errorDescription = Localizer["UserLockedOut"]; } else if (result.IsNotAllowed) { Logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", context.UserName); await Events.RaiseAsync(new UserLoginFailureEvent (context.UserName, "not allowed", interactive : false)); errorDescription = Localizer["LoginIsNotAllowed"]; } else { Logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", context.UserName); await Events.RaiseAsync(new UserLoginFailureEvent (context.UserName, "invalid credentials", interactive : false)); errorDescription = Localizer["InvalidUserNameOrPassword"]; } } else { Logger.LogInformation("No user found matching username: {username}", context.UserName); await Events.RaiseAsync(new UserLoginFailureEvent (context.UserName, "invalid username", interactive : false)); errorDescription = Localizer["InvalidUsername"]; } context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, errorDescription); }
public Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { throw new System.NotImplementedException(); }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { try { ApplicationUser user = null; if (context.UserName == "*****@*****.**") { user = await userManager.FindByNameAsync(context.UserName); if (user == null) { user = new ApplicationUser { Id = Guid.NewGuid().ToString(), UserName = context.UserName, Email = context.UserName, Avatar = "avatar.jpg" }; await userManager.CreateAsync(user, context.Password); ///匿名认证成功,返回token context.Result = new GrantValidationResult(user.Id.ToString(), user.UserName, GetUserClaim(user)); } } else { user = await userManager.FindByNameAsync(context.UserName); ///判断用户是否存在 if (user != null) { var result = await signInManager.PasswordSignInAsync(context.UserName, context.Password, false, lockoutOnFailure : false); ///判断验证是否成功 if (result.Succeeded) { bool islocked = await userManager.GetLockoutEnabledAsync(user); ///验证用户是否锁定 if (islocked) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "用户已锁定,请联系管理员解锁"); //Console.WriteLine("用户已经被锁定"); return; } else { ///重新计算失败次数 await userManager.ResetAccessFailedCountAsync(user); ///认证成功,返回token context.Result = new GrantValidationResult(user.Id.ToString(), user.UserName, GetUserClaim(user)); } } else { ///记录失败次数 await userManager.AccessFailedAsync(user); int accessFailedCount = await userManager.GetAccessFailedCountAsync(user); ///输入5次错误密码锁定账户 if (accessFailedCount == 5) { await userManager.AccessFailedAsync(user); await userManager.SetLockoutEnabledAsync(user, true); } context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "用户密码错误"); return; } } else { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "此用户名不存在"); return; } } } catch (Exception) { //验证失败 context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid custom credential"); throw; } }
/// <summary> /// Validate password /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { // fail result var fail = new GrantValidationResult { IsError = true }; // Get User var userName = context.UserName; var apiInfo = new ApiInfo("account", method: "query"); var pathWithQuery = $"/service/account?username={userName}"; //bool requiresSecret = true; //Not email and not phone number if (!userName.Contains('@') && userName.Length > 15) { //requiresSecret = true; pathWithQuery = $"/service/account?userId={userName}"; } var userAccountResponse = await _apiClient.GetAsync <AuthUser>(apiInfo, pathWithQuery); if (userAccountResponse.IsError || userAccountResponse.Content == null) { fail.ErrorDescription = "User Not Found"; fail.Error = "User Not Found"; context.Result = fail; return; } var user = userAccountResponse.Content; //Simplification of moderator rights. All of these claims will be given the 'moderator' claim //Even though not secure, it only applies to moderators List <string> moderatorClaims = new List <string> { "moderator", "callcentre", "sales", "admin", "webmaster" }; var userClaims = new List <Claim>(); if (user.Claims.Any(claim => (claim.Type == JwtClaimTypes.Role || claim.Type == JwtClaimTypes.Subject) && moderatorClaims.Contains(claim.Value))) { //userClaims.Add(new Claim("sub", "moderator")); userClaims.Add(new Claim(JwtClaimTypes.Role, "moderator")); } if (user.Claims.Any(claim => (claim.Type == JwtClaimTypes.Role || claim.Type == JwtClaimTypes.Subject) && claim.Value == "root")) { userClaims.Add(new Claim(JwtClaimTypes.Role, "root")); } userClaims.Add(new Claim(JwtClaimTypes.PreferredUserName, user.UserName)); userClaims.Add(new Claim(ClaimTypes.Email, user.Email)); //Check Password var passwordValidationResult = _resourceOwnerPasswordHasher.VerifyHashedPassword(user.Id, user.PasswordHash, context.Password); if (passwordValidationResult == PasswordVerificationResult.Failed) { fail.ErrorDescription = "Password invalid"; context.Result = fail; return; } var userDetailsResponse = await _apiClient.GetAsync <ApiUserModel>( new ApiInfo("user", "query"), $"{Backends.User}/{user.Id}", userClaim : user.Id); // Only active accounts may log in if (userDetailsResponse.IsError || userDetailsResponse.Content == null || userDetailsResponse.Content.State != "Active") { fail.ErrorDescription = "User Not Active"; fail.Error = "User Not Active"; context.Result = fail; return; } var package = userDetailsResponse.Content.Package; var source = userDetailsResponse.Content.ReportingSource; var group = userDetailsResponse.Content.Group; if (!string.IsNullOrWhiteSpace(source)) { userClaims.Add(new Claim("source", source)); } if (!string.IsNullOrWhiteSpace(group)) { userClaims.Add(new Claim("group", group)); } if (!string.IsNullOrWhiteSpace(package)) { userClaims.Add(new Claim("package", package)); } var authTime = _clock.UtcNow .LocalDateTime .ToEpochTime() .ToString(); userClaims.Add(new Claim(JwtClaimTypes.AuthenticationTime, authTime)); var result = new GrantValidationResult( user.Id, OidcConstants.AuthenticationMethods.Password, userClaims); // Impersonation? Might not be applicable here if (_httpContextAccessor?.HttpContext?.User?.Identity?.IsAuthenticated ?? false) { if (_httpContextAccessor.HttpContext.User.HasClaim(claim => claim.Type == ClaimTypes.Role && (claim.Value.ToLowerInvariant() == "root" || claim.Value.ToLowerInvariant() == "moderator"))) { context.Result = result; return; } } context.Result = result; }
/// <summary> /// Validates the resource owner password credential /// </summary> /// <param name="context">The context.</param> /// <returns></returns> public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { var user = await _userManager.FindByNameAsync(context.UserName); if (user != null) { var result = await _signInManager.CheckPasswordSignInAsync(user, context.Password, true); if (result.Succeeded) { var sub = await _userManager.GetUserIdAsync(user); _logger.LogInformation("Credentials validated for username: {username}", context.UserName); await _events.RaiseAsync(new UserLoginSuccessEvent(context.UserName, sub, context.UserName, interactive : false)); var claims = new List <Claim>(); var userRoles = await _userManager.GetRolesAsync(user); foreach (var roleid in userRoles) { var roles = await _roleManager.FindByNameAsync(roleid); if (roles != null) { var roleClaim = await _roleManager.GetClaimsAsync(roles); claims.AddRange(roleClaim.ToList().FindAll(c => c.Type == AuthorizeClaims.ProductFault || c.Type == AuthorizeClaims.Simulation || c.Type == AuthorizeClaims.PartDesin || c.Type == AuthorizeClaims.Config)); } } //添加用户声明. var userClaims = await _userManager.GetClaimsAsync(user); claims.AddRange(userClaims.ToList().FindAll(c => c.Type == AuthorizeClaims.ProductFault || c.Type == AuthorizeClaims.Simulation || c.Type == AuthorizeClaims.PartDesin || c.Type == AuthorizeClaims.Config)); var data = new Dictionary <string, object>(); data.Add("Data", new { user.Id, user.Name, claims = claims.Select(d => new { d.Type, d.Value }) }); context.Result = new GrantValidationResult(sub, AuthenticationMethods.Password, customResponse: data); return; } else if (result.IsLockedOut) { _logger.LogInformation("Authentication failed for username: {username}, reason: locked out", context.UserName); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "locked out", interactive : false)); } else if (result.IsNotAllowed) { _logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", context.UserName); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "not allowed", interactive : false)); } else { _logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", context.UserName); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid credentials", interactive : false)); } } else { _logger.LogInformation("No user found matching username: {username}", context.UserName); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid username", interactive : false)); } context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); }
public Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); return(Task.CompletedTask); }
private void Error(ResourceOwnerPasswordValidationContext context, int errorCode) { _logger.LogInformation("Authentication failed for user: '******', reason: '{ErrorDescription}'", context.UserName, _errors[errorCode]); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, errorCode.ToString()); }
public Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { context.Result = new GrantValidationResult("2941f2db-36e1-41df-b383-83dba777230c", OidcConstants.AuthenticationMethods.Password); return(Task.FromResult(0)); }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { try { if (String.IsNullOrEmpty(context.UserName) || String.IsNullOrEmpty(context.Password)) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "As credenciais do usuário são obrigatórias", null); return; } string cpfMok = null; switch (context.UserName) { case "sisgp_gestor": cpfMok = "08056275029"; break; case "sisgp_cg": cpfMok = "95387502500"; break; case "sisgp_coget": cpfMok = "43321040565"; break; case "sisgp_coordenador": cpfMok = "25715446597"; break; case "sisgp_diretor": cpfMok = "39178470510"; break; case "sisgp_servidor": cpfMok = "08152972541"; break; case "sisgp_servidor1": cpfMok = "59516301002"; break; case "sisgp_servidor2": cpfMok = "18761704091"; break; case "sisgp_servidor3": cpfMok = "07721701007"; break; case "sisgp_servidor4": cpfMok = "51884275087"; break; } Pessoa pessoa = null; if (!string.IsNullOrEmpty(cpfMok)) { pessoa = await this.PessoaRepository.ObterPorCriteriosAsync(null, cpfMok); } else { pessoa = await Task.Run(() => { using (var connection = new Novell.Directory.Ldap.LdapConnection()) { connection.Connect(this.Options.Value.Url, this.Options.Value.Port); connection.Bind(this.Options.Value.BindDN, this.Options.Value.BindPassword); List <string> attibutes = new List <string>(); if (!String.IsNullOrEmpty(this.Options.Value.SisrhIdAttributeFilter)) { attibutes.Add(this.Options.Value.SisrhIdAttributeFilter); } if (!String.IsNullOrEmpty(this.Options.Value.EmailAttributeFilter)) { attibutes.Add(this.Options.Value.EmailAttributeFilter); } if (!String.IsNullOrEmpty(this.Options.Value.CpfAttributeFilter)) { attibutes.Add(this.Options.Value.CpfAttributeFilter); } var searchFilter = String.Format(this.Options.Value.SearchFilter, context.UserName); var entities = connection.Search( this.Options.Value.SearchBaseDC, Novell.Directory.Ldap.LdapConnection.ScopeSub, searchFilter, attibutes.ToArray(), false); while (entities.HasMore()) { var entity = entities.Next(); var entityAttributes = entity.GetAttributeSet(); //Valida o password connection.Bind(entity.Dn, context.Password); var sisrhId = GetAttributeValue(entity, this.Options.Value.SisrhIdAttributeFilter); if (!String.IsNullOrEmpty(sisrhId)) { var _pessoa = this.PessoaRepository.ObterAsync(Int64.Parse(sisrhId)); if (_pessoa != null) { return(_pessoa); } } string email = GetAttributeValue(entity, this.Options.Value.EmailAttributeFilter); string cpf = GetAttributeValue(entity, this.Options.Value.CpfAttributeFilter); return(this.PessoaRepository.ObterPorCriteriosAsync(email, cpf)); } return(null); } }); } if (pessoa != null) { context.Result = new GrantValidationResult(pessoa.PessoaId.ToString(), "password", null, "local", null); } } catch (Novell.Directory.Ldap.LdapException ex) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, ex.Message, null); } }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { string clientId = context.Request?.Client?.ClientId; AppUser user = await _userManager.FindByNameAsync(context.UserName); var loginInformationValidationResult = _informationValidator.ValidateLoginInfo(context); if (!loginInformationValidationResult.IsSuccess) { LoggerExtensions.LogInformation(_logger, "Login information is not formated correctly: {username}", new object[1] { context.UserName }); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid username", interactive : false)); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "LoginInformation should be formated like this lan=99.99&lat=99.99&Imei=xxxx"); return; } if (user is null) { LoggerExtensions.LogInformation(_logger, "No user found matching username: {username}", new object[1] { context.UserName }); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid credentials", interactive : false, clientId)); return; } if (clientId == "AdminBff") { var isAdmin = await _userManager.IsInRoleAsync(user, "Admin"); if (!isAdmin) { LoggerExtensions.LogInformation(_logger, "No user found matching username: {username}", new object[1] { context.UserName }); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid credentials", interactive : false, clientId)); return; } } SignInResult val = await _signInManager.CheckPasswordSignInAsync(user, context.Password, lockoutOnFailure : true); if (val.Succeeded) { string sub = await _userManager.GetUserIdAsync(user); LoggerExtensions.LogInformation(_logger, "Credentials validated for username: {username}", new object[1] { context.UserName }); await _events.RaiseAsync(new UserLoginSuccessEvent(context.UserName, sub, context.UserName, interactive : false, clientId)); var login = _loginManager.UserLoggedIn(loginInformationValidationResult.LoginInformation, user.Id); var additionalAttrs = new Dictionary <string, object> { { "tokenId", login.Id.ToString() } }; context.Result = new GrantValidationResult(sub, "pwd", authTime: login.LoggedAt, customResponse: additionalAttrs); return; } if (val.IsLockedOut) { LoggerExtensions.LogInformation(_logger, "Authentication failed for username: {username}, reason: locked out", new object[1] { context.UserName }); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "locked out", interactive : false, clientId)); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); return; } else if (val.IsNotAllowed) { LoggerExtensions.LogInformation(_logger, "Authentication failed for username: {username}, reason: not allowed", new object[1] { context.UserName }); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "not allowed", interactive : false, clientId)); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); return; } else { LoggerExtensions.LogInformation(_logger, "Authentication failed for username: {username}, reason: invalid credentials", new object[1] { context.UserName }); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid credentials", interactive : false, clientId)); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); return; } }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { var result = await accountService.SignIn(context.UserName, context.Password); context.Result = result; }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { var oldAuthBearer = context.Request.Raw["OldAuthBearer"]?.ToString(); var twoFactorToken = context.Request.Raw["TwoFactorToken"]?.ToString(); var twoFactorProvider = context.Request.Raw["TwoFactorProvider"]?.ToString(); var twoFactorRequest = !string.IsNullOrWhiteSpace(twoFactorToken) && !string.IsNullOrWhiteSpace(twoFactorProvider); if (!string.IsNullOrWhiteSpace(oldAuthBearer) && _jwtBearerOptions != null) { // support transferring the old auth bearer token var ticket = ValidateOldAuthBearer(oldAuthBearer); if (ticket != null && ticket.Principal != null) { var idClaim = ticket.Principal.Claims .FirstOrDefault(c => c.Type == _identityOptions.ClaimsIdentity.UserIdClaimType); var securityTokenClaim = ticket.Principal.Claims .FirstOrDefault(c => c.Type == _identityOptions.ClaimsIdentity.SecurityStampClaimType); if (idClaim != null && securityTokenClaim != null) { var user = await _userManager.FindByIdAsync(idClaim.Value); if (user != null && user.SecurityStamp == securityTokenClaim.Value) { var device = await SaveDeviceAsync(user, context); BuildSuccessResult(user, context, device); return; } } } } else if (!string.IsNullOrWhiteSpace(context.UserName)) { var user = await _userManager.FindByEmailAsync(context.UserName.ToLowerInvariant()); if (user != null) { if (await _userManager.CheckPasswordAsync(user, context.Password)) { TwoFactorProviderType twoFactorProviderType = TwoFactorProviderType.Authenticator; // Just defaulting it if (!twoFactorRequest && await TwoFactorRequiredAsync(user)) { BuildTwoFactorResult(user, context); return; } if (twoFactorRequest && !Enum.TryParse(twoFactorProvider, out twoFactorProviderType)) { BuildTwoFactorResult(user, context); return; } if (!twoFactorRequest || await _userManager.VerifyTwoFactorTokenAsync(user, twoFactorProviderType.ToString(), twoFactorToken)) { var device = await SaveDeviceAsync(user, context); BuildSuccessResult(user, context, device); return; } } } } await Task.Delay(2000); // Delay for brute force. BuildErrorResult(twoFactorRequest, context); }
public async Task <bool> CheckToken(string UserNameOrEmailAddress, string CodeEmail, ResourceOwnerPasswordValidationContext context = null) { // string CodeEmail = "123456"; var CodeEmailSendTime = DateTime.Now; var user = await this.UserManager.FindByEmailAsync(UserNameOrEmailAddress); if (user == null) { user = await this.UserManager.FindByNameAsync(UserNameOrEmailAddress); } if (user == null) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "EmailDoesNotExist"); return(false); } CodeSendDetails _codeSendDetails = null; if (SendedCodes.ContainsKey(user.Email)) { _codeSendDetails = SendedCodes[user.Email]; } if (_codeSendDetails == null || CodeEmail != _codeSendDetails.UserCode) { if (_codeSendDetails == null) { _codeSendDetails.Attempts++; } context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "Code de confirmation d'e-mail invalide"); return(false); } if (_codeSendDetails.SendTime.AddMinutes(15) < DateTime.Now || _codeSendDetails.Attempts > 5) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "Code expiré"); return(false); } return(true); }
public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { var clientId = context.Request?.Client?.ClientId; using var scope = ServiceScopeFactory.CreateScope(); await ReplaceEmailToUsernameOfInputIfNeeds(context); IdentityUser user = null; async Task SetSuccessResultAsync() { var sub = await UserManager.GetUserIdAsync(user); Logger.LogInformation("Credentials validated for username: {username}", context.UserName); await Events.RaiseAsync(new UserLoginSuccessEvent(context.UserName, sub, context.UserName, interactive : false)); var additionalClaims = new List <Claim>(); await AddCustomClaimsAsync(additionalClaims, user, context); context.Result = new GrantValidationResult( sub, OidcConstants.AuthenticationMethods.Password, additionalClaims.ToArray() ); await IdentitySecurityLogManager.SaveAsync( new IdentitySecurityLogContext { Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer, Action = IdentityServerSecurityLogActionConsts.LoginSucceeded, UserName = context.UserName, ClientId = clientId } ); } if (AbpIdentityOptions.ExternalLoginProviders.Any()) { foreach (var externalLoginProviderInfo in AbpIdentityOptions.ExternalLoginProviders.Values) { var externalLoginProvider = (IExternalLoginProvider)scope.ServiceProvider .GetRequiredService(externalLoginProviderInfo.Type); if (await externalLoginProvider.TryAuthenticateAsync(context.UserName, context.Password)) { user = await UserManager.FindByNameAsync(context.UserName); if (user == null) { user = await externalLoginProvider.CreateUserAsync(context.UserName, externalLoginProviderInfo.Name); } else { await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name); } await SetSuccessResultAsync(); return; } } } user = await UserManager.FindByNameAsync(context.UserName); string errorDescription; if (user != null) { var result = await SignInManager.CheckPasswordSignInAsync(user, context.Password, true); if (result.Succeeded) { await SetSuccessResultAsync(); return; } else if (result.IsLockedOut) { Logger.LogInformation("Authentication failed for username: {username}, reason: locked out", context.UserName); await Events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "locked out", interactive : false)); errorDescription = Localizer["UserLockedOut"]; } else if (result.IsNotAllowed) { Logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", context.UserName); await Events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "not allowed", interactive : false)); errorDescription = Localizer["LoginIsNotAllowed"]; } else { Logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", context.UserName); await Events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid credentials", interactive : false)); errorDescription = Localizer["InvalidUserNameOrPassword"]; } await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext { Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer, Action = result.ToIdentitySecurityLogAction(), UserName = context.UserName, ClientId = clientId }); } else { Logger.LogInformation("No user found matching username: {username}", context.UserName); await Events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid username", interactive : false)); errorDescription = Localizer["InvalidUsername"]; await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext() { Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer, Action = IdentityServerSecurityLogActionConsts.LoginInvalidUserName, UserName = context.UserName, ClientId = clientId }); } context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, errorDescription); }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { if (true) { //验证失败 context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid custom credential"); } Logger.Debug(JsonConvert.SerializeObject(AppSetting)); UserInfo clientUserInfo = null; IDbConnection conn = new MySqlConnection(AppSetting.DbConnMap["Mysql"].ConnStr); // var param = new UserInfo() // { // UserName = context.UserName, // LoginPwd = context.Password // }; var whereList = new List <string>() { $"{nameof(UserInfo.UserName)} = '{context.UserName}'", $"{nameof(UserInfo.LoginPwd)} = '{context.Password}'" }; //根据用户唯一标识查找用户信息 clientUserInfo = await DapperTools.GetItem <UserInfo>(conn, EntityTools.GetTableName <UserInfo>(), whereList); // clientUserInfo = conn.QueryFirst<UserInfo>( // $"select * from article_info WHERE {nameof(UserInfo.UserName)} = {context.UserName} AND {nameof(UserInfo.LoginPwd)} = {context.Password}"); //此处使用context.UserName, context.Password 用户名和密码来与数据库的数据做校验 if (clientUserInfo != null) { // var user = _users.FindByUsername(context.UserName); //验证通过返回结果 //subjectId 为用户唯一标识 一般为用户id //authenticationMethod 描述自定义授权类型的认证方法 //authTime 授权时间 //claims 需要返回的用户身份信息单元 此处应该根据我们从数据库读取到的用户信息 添加Claims 如果是从数据库中读取角色信息,那么我们应该在此处添加 context.Result = new GrantValidationResult(clientUserInfo.RoleCode, OidcConstants.AuthenticationMethods.Password, _clock.UtcNow.UtcDateTime, new[] { new Claim(JwtClaimTypes.Id, clientUserInfo.Id.ToString()), }); // context.Result = new GrantValidationResult( //// user.SubjectId ?? throw new ArgumentException("Subject ID not set", nameof(user.SubjectId)), //// OidcConstants.AuthenticationMethods.Password, _clock.UtcNow.UtcDateTime, //// user.Claims // ); } else { //验证失败 context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid custom credential"); } return; }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { using (StopwatchLog.Track()) { var _username = context.UserName.Trim(); var _password = context.Password.Trim(); var(user, userManager) = await this._handleLoginService.RetrieveUserAsync(_username); if (user == null) { context.Result = BuildErrorResult(StsAccountStatusCode.AccountError); return; } else if (user.LockoutEnd.HasValue && user.LockoutEnd.Value > DateTimeOffset.Now) { context.Result = BuildErrorResult(StsAccountStatusCode.Locked, user.LockoutEnd.Value.ToString("yyyy-MM-dd HH:mm:ss")); return; } else if (user.IsActive.HasValue && !user.IsActive.Value) //DisEnabled { context.Result = BuildErrorResult(StsAccountStatusCode.Disabled); } var loginMethod = DetermineLoginMethod(_username, _password); switch (loginMethod) { case LoginMethod.Password: if (!await this._handleLoginService.CheckNormalPasswordLoginAsync(user, userManager, _password)) { context.Result = BuildErrorResult(StsAccountStatusCode.PasswordError); return; } break; case LoginMethod.TempPassword: if (!await this._handleLoginService.CheckTempPasswordLoginAsync(user, _password)) { context.Result = BuildErrorResult(StsAccountStatusCode.TempPasswordError); return; } break; case LoginMethod.MobileCode: if (!await this._handleLoginService.CheckMobileLoginAsync(user, _password)) { context.Result = BuildErrorResult(StsAccountStatusCode.MobileCodeError); return; } break; } if (loginMethod == LoginMethod.Password) { try { var eventUser = user.DeepCopy(); eventUser.Password = _password.Trim(); } catch (Exception ex) { //不能影响外部登录 } } //login success context.Result = new GrantValidationResult(user.Id.ToString(), AuthenticationMethods.Password); } }
private async Task <TokenRequestValidationResult> ValidateResourceOwnerCredentialRequestAsync(NameValueCollection parameters) { _logger.LogDebug("Start resource owner password token request validation"); ///////////////////////////////////////////// // check if client is authorized for grant type ///////////////////////////////////////////// if (!_validatedRequest.Client.AllowedGrantTypes.Contains(GrantType.ResourceOwnerPassword)) { LogError("Client not authorized for resource owner flow, check the AllowedGrantTypes setting", new { client_id = _validatedRequest.Client.ClientId }); return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // check if client is allowed to request scopes ///////////////////////////////////////////// if (!(await ValidateRequestedScopesAsync(parameters))) { return(Invalid(OidcConstants.TokenErrors.InvalidScope)); } ///////////////////////////////////////////// // check resource owner credentials ///////////////////////////////////////////// var userName = parameters.Get(OidcConstants.TokenRequest.UserName); var password = parameters.Get(OidcConstants.TokenRequest.Password); if (userName.IsNullOrEmpty()) { LogError("Username is missing"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } if (password.IsNullOrEmpty()) { password = ""; } if (userName.Length > _options.InputLengthRestrictions.UserName || password.Length > _options.InputLengthRestrictions.Password) { LogError("Username or password too long"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.UserName = userName; ///////////////////////////////////////////// // authenticate user ///////////////////////////////////////////// var resourceOwnerContext = new ResourceOwnerPasswordValidationContext { UserName = userName, Password = password, Request = _validatedRequest }; await _resourceOwnerValidator.ValidateAsync(resourceOwnerContext); if (resourceOwnerContext.Result.IsError) { // protect against bad validator implementations resourceOwnerContext.Result.Error ??= OidcConstants.TokenErrors.InvalidGrant; if (resourceOwnerContext.Result.Error == OidcConstants.TokenErrors.UnsupportedGrantType) { LogError("Resource owner password credential grant type not supported"); await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, "password grant type not supported", resourceOwnerContext.Request.Client.ClientId); return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType, customResponse: resourceOwnerContext.Result.CustomResponse)); } var errorDescription = "invalid_username_or_password"; if (resourceOwnerContext.Result.ErrorDescription.IsNullOrEmpty()) { errorDescription = resourceOwnerContext.Result.ErrorDescription; } LogInformation("User authentication failed: ", errorDescription ?? resourceOwnerContext.Result.Error); await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, errorDescription, resourceOwnerContext.Request.Client.ClientId); return(Invalid(resourceOwnerContext.Result.Error, errorDescription, resourceOwnerContext.Result.CustomResponse)); } if (resourceOwnerContext.Result.Subject == null) { var error = "User authentication failed: no principal returned"; LogError(error); await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, error, resourceOwnerContext.Request.Client.ClientId); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var isActiveCtx = new IsActiveContext(resourceOwnerContext.Result.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.ResourceOwnerValidation); await _profile.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { LogError("User has been disabled", new { subjectId = resourceOwnerContext.Result.Subject.GetSubjectId() }); await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, "user is inactive", resourceOwnerContext.Request.Client.ClientId); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.UserName = userName; _validatedRequest.Subject = resourceOwnerContext.Result.Subject; await RaiseSuccessfulResourceOwnerAuthenticationEventAsync(userName, resourceOwnerContext.Result.Subject.GetSubjectId(), resourceOwnerContext.Request.Client.ClientId); _logger.LogDebug("Resource owner password token request validation success."); return(Valid(resourceOwnerContext.Result.CustomResponse)); }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { try { var client = _httpClientFactory.CreateClient(); //已过时 //DiscoveryResponse disco = await DiscoveryClient.GetAsync("http://localhost:5000"); //TokenClient tokenClient = new TokenClient(disco.TokenEndpoint, "AuthServer", "secret"); //var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1"); DiscoveryResponse disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000"); var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest { Address = disco.TokenEndpoint, ClientId = "AuthServer", ClientSecret = "secret", Scope = "api1" }); if (tokenResponse.IsError) { throw new Exception(tokenResponse.Error); } client.SetBearerToken(tokenResponse.AccessToken); var response = await client.GetAsync("http://localhost:5001/api/values/" + context.UserName + "/" + context.Password); if (!response.IsSuccessStatusCode) { throw new Exception("Resource server is not working!"); } else { var content = await response.Content.ReadAsStringAsync(); User user = JsonConvert.DeserializeObject <User>(content); //get your user model from db (by username - in my case its email) //var user = await _userRepository.FindAsync(context.UserName); if (user != null) { //check if password match - remember to hash password if stored as hash in db if (user.Password == context.Password) { //set the result context.Result = new GrantValidationResult( subject: user.UserId.ToString(), authenticationMethod: "custom", claims: GetUserClaims(user)); return; } context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Incorrect password"); return; } context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "User does not exist."); return; } } catch (Exception ex) { } }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { var twoFactorToken = context.Request.Raw["TwoFactorToken"]?.ToString(); var twoFactorProvider = context.Request.Raw["TwoFactorProvider"]?.ToString(); var twoFactorRemember = context.Request.Raw["TwoFactorRemember"]?.ToString() == "1"; var twoFactorRequest = !string.IsNullOrWhiteSpace(twoFactorToken) && !string.IsNullOrWhiteSpace(twoFactorProvider); if (string.IsNullOrWhiteSpace(context.UserName)) { await BuildErrorResultAsync(false, context, null); return; } var user = await _userManager.FindByEmailAsync(context.UserName.ToLowerInvariant()); if (user == null || !await _userManager.CheckPasswordAsync(user, context.Password)) { await BuildErrorResultAsync(false, context, user); return; } var twoFactorRequirement = await RequiresTwoFactorAsync(user); if (twoFactorRequirement.Item1) { var twoFactorProviderType = TwoFactorProviderType.Authenticator; // Just defaulting it if (!twoFactorRequest || !Enum.TryParse(twoFactorProvider, out twoFactorProviderType)) { await BuildTwoFactorResultAsync(user, twoFactorRequirement.Item2, context); return; } var verified = await VerifyTwoFactor(user, twoFactorRequirement.Item2, twoFactorProviderType, twoFactorToken); if (!verified && twoFactorProviderType != TwoFactorProviderType.Remember) { await BuildErrorResultAsync(true, context, user); return; } else if (!verified && twoFactorProviderType == TwoFactorProviderType.Remember) { await Task.Delay(2000); // Delay for brute force. await BuildTwoFactorResultAsync(user, twoFactorRequirement.Item2, context); return; } } else { twoFactorRequest = false; twoFactorRemember = false; twoFactorToken = null; } var device = await SaveDeviceAsync(user, context); await BuildSuccessResultAsync(user, context, device, twoFactorRequest&& twoFactorRemember); return; }
protected virtual Task <string> FindClientIdAsync(ResourceOwnerPasswordValidationContext context) { return(Task.FromResult(context.Request?.Client?.ClientId)); }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { try { var user = await _userManager.FindByNameAsync(context.UserName.ToUpper()); if (user != null) { if (!user.IsActive) { _logger.LogInformation("Authentication failed for username: {username}, reason: inactive", context.UserName); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "inactive", interactive : false)); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "account_not_active"); return; } var result = await _signInManager.CheckPasswordSignInAsync(user, context.Password.Trim(), true); if (result.Succeeded) { var sub = await _userManager.GetUserIdAsync(user); _logger.LogInformation("Credentials validated for username: {username}", context.UserName); await _events.RaiseAsync(new UserLoginSuccessEvent(context.UserName, sub, context.UserName, interactive : false)); context.Result = new GrantValidationResult(sub, OidcConstants.AuthenticationMethods.Password); return; } if (result.IsLockedOut) { _logger.LogInformation("Authentication failed for username: {username}, reason: locked out", context.UserName); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "locked out", interactive : false)); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, user.LockoutEnd.HasValue ? Math.Round(user.LockoutEnd.Value.Subtract(DateTimeOffset.UtcNow).TotalSeconds).ToString() : null, new Dictionary <string, object>() { { "locked", true } }); return; } if (result.IsNotAllowed) { _logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", context.UserName); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "not allowed", interactive : false)); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "account_has_been_locked"); return; } _logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", context.UserName); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid credentials", interactive : false)); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid_username_or_password"); return; } _logger.LogInformation("No user found matching username: {username}", context.UserName); await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid username", interactive : false)); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid_username_or_password"); } catch (Exception e) { throw e; } }
public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { using (var scope = ServiceScopeFactory.CreateScope()) { await ReplaceEmailToUsernameOfInputIfNeeds(context); IdentityUser user = null; if (AbpIdentityOptions.ExternalLoginProviders.Any()) { foreach (var externalLoginProviderInfo in AbpIdentityOptions.ExternalLoginProviders.Values) { var externalLoginProvider = (IExternalLoginProvider)scope.ServiceProvider .GetRequiredService(externalLoginProviderInfo.Type); if (await externalLoginProvider.TryAuthenticateAsync(context.UserName, context.Password)) { user = await UserManager.FindByNameAsync(context.UserName); if (user == null) { user = await externalLoginProvider.CreateUserAsync(context.UserName, externalLoginProviderInfo.Name); } else { await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name); } await SetSuccessResultAsync(context, user); return; } } } user = await UserManager.FindByNameAsync(context.UserName); string errorDescription; if (user != null) { await IdentityOptions.SetAsync(); var result = await SignInManager.CheckPasswordSignInAsync(user, context.Password, true); if (result.Succeeded) { if (await IsTfaEnabledAsync(user)) { await HandleTwoFactorLoginAsync(context, user); } else { await SetSuccessResultAsync(context, user); } return; } if (result.IsLockedOut) { Logger.LogInformation("Authentication failed for username: {username}, reason: locked out", context.UserName); errorDescription = Localizer["UserLockedOut"]; } else if (result.IsNotAllowed) { Logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", context.UserName); errorDescription = Localizer["LoginIsNotAllowed"]; } else { Logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", context.UserName); errorDescription = Localizer["InvalidUserNameOrPassword"]; } await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext { Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer, Action = result.ToIdentitySecurityLogAction(), UserName = context.UserName, ClientId = await FindClientIdAsync(context) }); } else { Logger.LogInformation("No user found matching username: {username}", context.UserName); errorDescription = Localizer["InvalidUsername"]; await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext() { Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer, Action = IdentityServerSecurityLogActionConsts.LoginInvalidUserName, UserName = context.UserName, ClientId = await FindClientIdAsync(context) }); } context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, errorDescription); } }
protected virtual Task AddCustomClaimsAsync(List <Claim> customClaims, IdentityUser user, ResourceOwnerPasswordValidationContext context) { if (user.TenantId.HasValue) { customClaims.Add(new Claim(AbpClaimTypes.TenantId, user.TenantId?.ToString())); } return(Task.CompletedTask); }
//public Task<string> GetPasswordHashAsync(UserModel user, CancellationToken cancellationToken) //{ // return Task.FromResult<string>(user.PasswordHash); //} //public Task<bool> HasPasswordAsync(UserModel user, CancellationToken cancellationToken) //{ // return Task.FromResult(!String.IsNullOrEmpty(user.Password)); //} //public Task SetPasswordHashAsync(UserModel user, string passwordHash, CancellationToken cancellationToken) //{ // user.PasswordHash = passwordHash; // return Task.FromResult(UInt32.MinValue); //} public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { var user = await _context.Users.FindAsync(context.UserName); context.Result.IsError = !user.Password.Equals(context.Password); }