在@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(登录名或一些唯一标识符(,然后端点应该检查用户是否存在,如果是,那么它应该通过短信发送密码。
然后用户将在我的表单中输入该密码,第二个请求将使用用户 ID 和密码标记端点路径。
我已经阅读了有关双因素身份验证(http://bitoftech.net/2014/10/15/two-factor-authentication-asp-net-web-api-angularjs-google-authenticator/和其他来源(的信息,但它要求用户使用用户名和密码登录,然后从短信提交第二个密码。
就我而言,我希望用户仅传递用户名和短信密码。
编辑:下面是我尝试构建的代码,它是起点,但我不知道如何完成实现它。我已经覆盖了GrantCustomExtension
OAuthAuthorizationServerProvider
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);
}
这是Startup的一部分.cs负责设置oAuthAuthorizationServer:
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并在数据库中查找用户,但最难的部分仍然缺失。我知道我可以将一次性密码存储在用户表中,但也许ASP.Net Identity 2
内置机制,我不想重新发明轮子。
您可以通过每次更改用户密码来做到这一点。
不知道在您的情况下是否被接受
如果您对此解决方案感兴趣,请按以下步骤操作:
用户经理
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
}