ASP.Net Identity 2 使用 SMS 密码登录 - 不使用双因素身份验证

Posted

技术标签:

【中文标题】ASP.Net Identity 2 使用 SMS 密码登录 - 不使用双因素身份验证【英文标题】:ASP.Net Identity 2 login using password from SMS - not using two-factor authentication 【发布时间】:2016-04-15 09:11:55 【问题描述】:

在@Taiseer Joudeh (http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/) 的博客系列之后,我使用 JWT 身份验证构建了简单的 WebApi。我可以使用令牌登录和查询我的端点。

我正在尝试更改我的登录机制的工作方式。 现在用户必须将他的登录名和密码发送到/oauth/token 以获得访问令牌,该令牌将随每个请求发送到 webapi。

我希望能够使用密码登录用户,该密码将通过短信发送到分配给他帐户的电话号码。

它应该需要两个请求来标记端点路径。第一个只有用户 ID(登录名或某些唯一标识符),然后端点应检查用户是否存在,如果是,则应通过 SMS 发送密码。 然后用户将在我的表单中输入该密码,并使用用户 ID 和密码对令牌端点路径进行第二次请求。

我已经阅读了双因素身份验证(http://bitoftech.net/2014/10/15/two-factor-authentication-asp-net-web-api-angularjs-google-authenticator/ 和其他来源),但它要求用户使用用户名和密码登录,然后通过 SMS 提交第二个密码。

在我的情况下,我希望用户只传递用户名和 SMS 密码。

编辑: 下面是我尝试构建的代码,它是起点,但我不知道如何完成它。我已经在 OAuthAuthorizationServerProvider 中覆盖了 GrantCustomExtension

public override async Task GrantCustomExtension(OAuthGrantCustomExtensionContext context)

    const string allowedOrigin = "*";
    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[]  allowedOrigin );

    //custom grant_type
    if (context.GrantType != "sms")
    
        context.SetError("invalid_grant", "unsupported grant_type");
        return;
    

    var userName = context.Parameters.Get("username");
    if (userName == null)
    
        context.SetError("invalid_grant", "username is required");
        return;
    

    var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
    ApplicationUser user = await userManager.FindByNameAsync(userName);
    if (user == null)
    
        context.SetError("invalid_grant", "user not found");
        return;
    

    //generate one-time password
    //store it in database
    //send it to user phone number
    //return ok message

    context.Validated();

    //return base.GrantCustomExtension(context);

这里是负责设置 oAuthAuthorizationServer 的 Startup.cs 的一部分:

public void ConfigureOAuthTokenGeneration(IAppBuilder app)

    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

    var issuer = ConfigurationManager.AppSettings["Issuer"];

    OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions()
    
        #if DEBUG
        AllowInsecureHttp = true,
        #endif
        TokenEndpointPath = new PathString("/oauth/token"),
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1),
        Provider = new CustomOAuthProvider(),
        AccessTokenFormat = new CustomJwtFormat(issuer)
    ;

    // OAuth 2.0 Bearer Access Token Generation
    app.UseOAuthAuthorizationServer(oAuthServerOptions);


我能够发送自定义 grant_type 并在数据库中查找用户,但最难的部分仍然缺失。我知道我可以将一次性密码存储在 User 表中,但也许 ASP.Net Identity 2 有内置机制,我不想重新发明***。

【问题讨论】:

为什么要投反对票? 【参考方案1】:

您可以通过每次更改用户密码来做到这一点。

不知道你的情况是否可以接受

如果您对此解决方案感兴趣,可以按照以下方式进行操作:

用户管理器

    ApplicationUserManager _userManager;

    public ApplicationUserManager UserManager
    
        get
        
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        
        private set
        
            _userManager = value;
        
    

// get your user here
var currentUser = UserManager.Users...
            if (currentUser != null)
            
                var resultRemove = UserManager.RemovePassword(currentUser.Id);
                var resultAdd = UserManager.AddPassword(currentUser.Id, model.NewPassword);
                if (resultAdd.Succeeded && resultRemove.Succeeded)
                    //Send SMS here
            

【讨论】:

感谢分享您的代码。这可能会奏效。我已经添加了到目前为止的代码。缺少的部分是生成一次性通行证,将其保存到数据库(您的答案会有所帮助),发送 SMS(非常简单)并从 OAuthAuthorizationServerProvider 返回正确答案。你能帮我解决这个问题吗? 那你在哪一部分需要帮助? 最后一个 - 现在从 /oauth/token 返回正确响应,即使我找到正确的用户,我的端点总是返回 BadRequest 和 unsupported_grant_type。我想返回 OK (200) 并发送消息“密码发送” 看看这个可能有帮助:***.com/questions/29360349/…>和这个:***.com/questions/29246908/…> 很抱歉之前没有写过,但是如果我使用grant_type 的密码发送请求,我会得到正确的响应,当使用grant_type 的sms 发送相同的数据时,我会得到BadRequest。我将使用我的 oAuthServerOptions 将启动类添加到我的问题中。

以上是关于ASP.Net Identity 2 使用 SMS 密码登录 - 不使用双因素身份验证的主要内容,如果未能解决你的问题,请参考以下文章

使用 twilio 来自 asp.net 的异步 SMS

在 ASP.NET 中使用 Identity 2.1 对用户进行身份验证和授权

Asp.NET Identity 2 给出“无效令牌”错误

ASP.NET Identity 2.0 注销不起作用

在 ASP.NET Identity 2.0 中获取当前用户 ID

Asp.net Identity 2.0 更新用户