ASP.Net Identity 2 login using password from SMS - not using two-factor authentication

牧云@^-^@ 提交于 2019-12-10 11:34:08

问题


Following blog series by @Taiseer Joudeh (http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/) I've build simple WebApi with JWT authentication. I'm able to login and query my endpoint using token.

I'm trying to change how my login mechanism works.
Right now user must send his login and password to /oauth/token to get access token that will be send with every request to webapi.

I'd like to be able to login user with password that will be send via SMS to phone number assigned to his account.

It should require two requests to token endpoint path. First one with only user id (login or some unique identifier), then endpoint should check if user exists, if yes then it should send password via SMS.
Then user would input that password in my form and second request would be done to token endpoint path with both user id and password.

I've read about two-factor authentication (http://bitoftech.net/2014/10/15/two-factor-authentication-asp-net-web-api-angularjs-google-authenticator/ and other sources), but it requires user to login using username and password and then to submit second password from SMS.

In my case I want user to pass only username and SMS password.

EDIT: Below is code I've tried to build, it is starting point, but I don't know how to finish implementing it. I've overriden GrantCustomExtension in 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);
}

And here is part of Startup.cs that is responsible for setting up 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);

}

I'm able to send custom grant_type and find user in database, but the hardest part is still missing. I know I can store that one-time password in User table, but maybe ASP.Net Identity 2 has build in mechanism, I dont want to reinvent the wheel.


回答1:


You can do it by changing the user password every time.

dont know if is accepted in your situation

In case you are interested in this solution, here is how you can do it:

User Manager

    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
            }


来源:https://stackoverflow.com/questions/36642938/asp-net-identity-2-login-using-password-from-sms-not-using-two-factor-authenti

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!