From c823e41a9968898653944e9f1e643d0aa1292e72 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 9 Aug 2019 13:14:32 +0800 Subject: [PATCH 1/2] Resolve #1512 AbpResourceOwnerPasswordValidator support custom claims. --- .../AbpResourceOwnerPasswordValidator.cs | 88 ++++++++++++++++--- 1 file changed, 75 insertions(+), 13 deletions(-) diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs index 778b3445bf7..946813aff88 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs @@ -1,33 +1,95 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Security.Claims; +using System.Threading.Tasks; +using IdentityModel; using IdentityServer4.AspNetIdentity; +using IdentityServer4.Events; +using IdentityServer4.Models; using IdentityServer4.Services; using IdentityServer4.Validation; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Volo.Abp.Identity; +using Volo.Abp.Security.Claims; using Volo.Abp.Uow; namespace Volo.Abp.IdentityServer.AspNetIdentity { - public class AbpResourceOwnerPasswordValidator : ResourceOwnerPasswordValidator + public class AbpResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator //ResourceOwnerPasswordValidator { + private readonly SignInManager _signInManager; + private readonly IEventService _events; + private readonly UserManager _userManager; + private readonly ILogger> _logger; + public AbpResourceOwnerPasswordValidator( - IdentityUserManager userManager, - SignInManager signInManager, - IEventService events, - ILogger> logger - ) : base( - userManager, - signInManager, - events, - logger) + UserManager userManager, + SignInManager signInManager, + IEventService events, + ILogger> logger) { + _userManager = userManager; + _signInManager = signInManager; + _events = events; + _logger = logger; } + /// + /// https://github.com/IdentityServer/IdentityServer4/blob/master/src/AspNetIdentity/src/ResourceOwnerPasswordValidator.cs#L53 + /// + /// + /// [UnitOfWork] - public override async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) + public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { - await base.ValidateAsync(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)); + + context.Result = new GrantValidationResult(sub, OidcConstants.AuthenticationMethods.Password, GetAdditionalClaimsOrNull(user)); + + 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); + } + + protected virtual IEnumerable GetAdditionalClaimsOrNull(IdentityUser user) + { + if (!user.TenantId.HasValue) + { + return null; + } + + return new[] { new Claim(AbpClaimTypes.TenantId, user.TenantId?.ToString()) }; } } } From 905baffdc6bdd39b27a17aa3a1d5faa60bfd357d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 15 Aug 2019 14:53:36 +0300 Subject: [PATCH 2/2] Resolved #1498: Set IServiceProvider in ValidationContext. --- .../DataAnnotationObjectValidationContributor.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs index 5598fe78274..797721bea3b 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; @@ -13,10 +14,14 @@ public class DataAnnotationObjectValidationContributor : IObjectValidationContri { public const int MaxRecursiveParameterValidationDepth = 8; + protected IServiceProvider ServiceProvider { get; } protected AbpValidationOptions Options { get; } - public DataAnnotationObjectValidationContributor(IOptions options) + public DataAnnotationObjectValidationContributor( + IOptions options, + IServiceProvider serviceProvider) { + ServiceProvider = serviceProvider; Options = options.Value; } @@ -90,7 +95,7 @@ public void AddErrors(List errors, object validatingObject) if (validatingObject is IValidatableObject validatableObject) { errors.AddRange( - validatableObject.Validate(new ValidationContext(validatableObject)) + validatableObject.Validate(new ValidationContext(validatableObject, ServiceProvider, null)) ); } } @@ -103,7 +108,7 @@ protected virtual void AddPropertyErrors(object validatingObject, PropertyDescri return; } - var validationContext = new ValidationContext(validatingObject) + var validationContext = new ValidationContext(validatingObject, ServiceProvider, null) { DisplayName = property.DisplayName, MemberName = property.Name