我正在使用Identity Server4和.net Core5身份进行身份验证服务,我使用此代码来获取我搜索的令牌,但无法接受任何解决方案...
// 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:在这一步中,我可以找到有手机号的userName,因为用户之前已经注册过,并检查动态口令进行验证
5:如何仅通过UserName或手机号生成token,并设置所有理赔?!
发布于 2021-08-31 10:23:25
您可以扩展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);
}
}
}https://stackoverflow.com/questions/68976048
复制相似问题