【问题标题】:Use Identityserver4 for Custom authentication to get token by OTP Mobile Number or only User Name使用 Identityserver4 进行自定义身份验证,通过 OTP 手机号码或仅用户名获取令牌
【发布时间】:2021-10-28 17:30:53
【问题描述】:

我正在使用 Identity Server 4 和 .net Core 5 Identity 进行身份验证服务 我使用此代码获取令牌 我已经搜索过,但没有任何可接受的解决方案...

        // discover endpoints from metadata
        var disco = await client.GetDiscoveryDocumentAsync(_siteSetting.IdentitySettings.IdentityServerUrl);
        if (disco.IsError)
            throw new BadRequestException(disco.Error);
        // request token
        var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
        {
            Address = disco.TokenEndpoint,
            ClientId = "MYClientId",
            ClientSecret = "secret_for_the_MYClientId",

            Scope = "ApiName roles",
            UserName = dto.userName,
            Password = dto.Password,
        });

我可以通过用户名和密码获取令牌 注册后,我想用OTP实现登录

1:用户发送电话号码

2:在后台生成OTP并保存,然后调用第三方服务发送到手机号

3:用户用手机号发送token

4:在这一步中,我可以找到带有手机号码的用户名 因为用户之前注册并检查了 OTP 以进行验证

5:如何仅通过用户名或手机号码生成令牌并设置所有声明?!

【问题讨论】:

    标签: c# authentication token identityserver4 one-time-password


    【解决方案1】:

    您可以扩展IResourceOwnerPasswordValidator 并覆盖ValidateAsync 方法

    您可以通过用户名和代码或电话和代码来检查,而不是通过用户和密码进行检查。 检查下面的实现并将CheckPasswordSignInAsync替换为您的实现,如果成功则提高UserLoginSuccessEvent,如果不成功则提高UserLoginFailureEvent

    public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
    {
    
        private readonly SignInManager<ApplicationUser> _signInManager;
        private IEventService _events;
        private readonly IHttpContextAccessor _context;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly ILogger<ResourceOwnerPasswordValidator<ApplicationUser>> _logger;
    
        /// <summary>
        /// Initializes a new instance of the <see cref="ResourceOwnerPasswordValidator{TUser}"/> class.
        /// </summary>
        /// <param name="userManager">The user manager.</param>
        /// <param name="signInManager">The sign in manager.</param>
        /// <param name="events">The events.</param>
        /// <param name="logger">The logger.</param>
        public ResourceOwnerPasswordValidator(
            UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager,
            IEventService events,
    
            ILogger<ResourceOwnerPasswordValidator<ApplicationUser>> logger, IHttpContextAccessor context)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _events = events;
            _logger = logger;
            _context = context;
        }
    
        //this is used to validate your user account with provided grant at /connect/token
        public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
        {
            {
    
                var user = await _userManager.FindByNameAsync(context.UserName);
                if (user == null) user = await _userManager.FindByEmailAsync(context.UserName);
                if (user != null)
                {
                    // 
                    var result = await _signInManager.CheckPasswordSignInAsync(user, context.Password, true);
                    if (result.Succeeded)
                    {
                    
    
                        _logger.LogInformation("Credentials validated for username: {username}", context.UserName);
                        await _events.RaiseAsync(new UserLoginSuccessEvent(context.UserName, user.Id, context.UserName, interactive: false));
    
                        context.Result = new GrantValidationResult(user.Id, AuthenticationMethods.Password);
                        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));
                        context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "account is locked out try after 5 min");
                        return;
                    }
                    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);
    
            }
    
    
    
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      • 2017-07-03
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      • 2020-04-22
      • 2014-10-30
      相关资源
      最近更新 更多