ASP.Net Identity 2-来自OAuthAuthorizationServerProvider的自定义响应

使命

这个问题是我上一个问题的延续:使用来自SMS的密码登录ASP.Net Identity 2-不使用两因素身份验证

我已经构建了自定义的OAuthAuthorizationServerProvider以支持自定义的grant_type。
我的想法是创建一个grant_type sms,允许用户生成一次性访问代码,该代码将发送到他的手机,然后在发送带有password_grant_type的请求时以用户身份作为密码。

现在,通过SMS生成,存储和发送该密码后,我想返回自定义响应,而不是我的GrantCustomExtension中的令牌。

public override async Task GrantCustomExtension(OAuthGrantCustomExtensionContext context)
{
    const string allowedOrigin = "*";
    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] {allowedOrigin});

    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;
    }

    var generator = new TotpSecurityStampBasedTokenProvider<ApplicationUser, string>();
    await userManager.UpdateSecurityStampAsync(user.Id);
    var accessCode = await generator.GenerateAsync("SMS", userManager, user);

    var accessCodeExpirationTime = TimeSpan.FromMinutes(5);

    var result = await userManager.AddAccessCode(user, accessCode, accessCodeExpirationTime);


    if(result.Succeeded)
    {
        Debug.WriteLine("Login code:"+accessCode);
        //here I'll send login code to user phone via SMS
    }


    //return 200 (OK)
    //with content type="application/json; charset=utf-8"
    //and custom json content {"message":"code send","expires_in":300}

    //skip part below

    ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "SMS");

    var ticket = new AuthenticationTicket(oAuthIdentity, null);

    context.Validated(ticket);

}

如何停止生成令牌并从OAuthAuthorizationServerProvider返回自定义响应?

我知道两种方法:TokenEndpoint,,TokenEndpointResponse但我想覆盖整个响应,而不仅仅是令牌。

编辑:
目前,我正在GrantCustomExtension使用以下代码创建临时ClaimsIdentity

var ci = new ClaimsIdentity();
ci.AddClaim(new Claim("message","send"));
ci.AddClaim(new Claim("expires_in", accessCodeExpirationTime.TotalSeconds.ToString(CultureInfo.InvariantCulture)));
context.Validated(ci);

而我覆盖TokenEndpointResponse

public override Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context)
{
    if (context.TokenEndpointRequest.GrantType != "sms") return base.TokenEndpointResponse(context);
    //clear response containing temporary token.
    HttpContext.Current.Response.SuppressContent = true;
    return Task.FromResult<object>(null);
}

这有两个问题:打电话时,context.Validated(ci);我是说这是一个有效的用户,但我想响应我已通过SMS发送访问代码的信息。HttpContext.Current.Response.SuppressContent = true;清除响应,但我想返回一些内容而不是空的响应。

费德里科·迪皮玛(Federico Dipuma)

这比最终解决方案更像是一种解决方法,但我认为这是解决问题的最可靠方法,而无需从默认OAuthAuthorizationServerProvider实现中重写大量代码

该方法很简单:使用Owin中间件来捕获令牌请求,并在发送SMS时覆盖响应。

[注释后编辑]修复了根据此答案可以缓存和更改响应正文的代码https://stackoverflow.com/a/36414238/965722

在您的Startup.cs文件内:

public void Configuration(IAppBuilder app)
{
    var tokenPath = new PathString("/Token"); //the same path defined in OAuthOptions.TokenEndpointPath

    app.Use(async (c, n) =>
    {
        //check if the request was for the token endpoint
        if (c.Request.Path == tokenPath)
        {
            var buffer = new MemoryStream();
            var body = c.Response.Body;
            c.Response.Body = buffer; // we'll buffer the response, so we may change it if needed

            await n.Invoke(); //invoke next middleware (auth)

            //check if we sent a SMS
            if (c.Get<bool>("sms_grant:sent"))
            {
                var json = JsonConvert.SerializeObject(
                    new
                    {
                        message = "code send",
                        expires_in = 300
                    });

                var bytes = Encoding.UTF8.GetBytes(json);

                buffer.SetLength(0); //change the buffer
                buffer.Write(bytes, 0, bytes.Length);

                //override the response headers
                c.Response.StatusCode = 200;
                c.Response.ContentType = "application/json";
                c.Response.ContentLength = bytes.Length;
            }

            buffer.Position = 0; //reset position
            await buffer.CopyToAsync(body); //copy to real response stream
            c.Response.Body = body; //set again real stream to response body
        }
        else
        {
            await n.Invoke(); //normal behavior
        }
    });

    //other owin middlewares in the pipeline
    //ConfigureAuth(app);

    //app.UseWebApi( .. );
}

在您的自定义授予方法中:

// ...
var result = await userManager.AddAccessCode(user, accessCode, accessCodeExpirationTime);


if(result.Succeeded)
{
    Debug.WriteLine("Login code:"+accessCode);
    //here I'll send login code to user phone via SMS
}

context.OwinContext.Set("sms_grant:sent", true);

//you may validate the user or set an error, doesn't matter anymore
//it will be overwritten
//...

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Asp.net Identity 2自定义用户和自定义表名称

来自分类Dev

如何自定义Asp.net Identity 2用户名已采取的验证消息?

来自分类Dev

自定义Asp.Net Identity 3.0

来自分类Dev

ASP .NET Identity-自定义IUserStore FindByNameAsync方法

来自分类Dev

如何使用 Asp.Net Identity 检查 Azure 表中是否存在记录并返回自定义响应

来自分类Dev

.Net Identity 2自定义验证文本

来自分类Dev

ASP.Net Identity 2 RemovePassword模拟

来自分类Dev

ASP.Net Identity 2 RemovePassword模拟

来自分类Dev

Asp.net Identity 2.0使用自定义唯一属性扩展UserValidator

来自分类Dev

在ASP.NET Identity中为AspNetUsers表使用自定义属性

来自分类Dev

ASP.NET Identity外部身份验证提供程序自定义图标

来自分类Dev

自定义ASP.NET Identity(OWIN)使用实体框架的详细信息

来自分类Dev

使用自定义角色在ASP.NET Identity中初始化RoleManager

来自分类Dev

在ASP.NET Identity中自定义IdentityUser类时,将创建可空字段

来自分类Dev

自定义MVC5 ASP.NET Identity中的cookie值

来自分类Dev

使用ASP.NET Identity 2.0和MVC 5的自定义单点登录

来自分类Dev

自定义MVC5 ASP.NET Identity中的cookie值

来自分类Dev

将自定义列添加到ASP.NET Identity

来自分类Dev

使用ASP.NET Identity 3的自定义密码策略

来自分类Dev

在MVC 5中的ASP.NET Identity 3上管理自定义用户属性

来自分类Dev

使用自定义 List<property> 扩展 ASP .NET Identity 并在视图中访问它

来自分类Dev

如何为 Asp.Net Identity 自定义表名(例如从 AspNetUsers 更改为自定义名称)

来自分类Dev

ASP.net Web API 2自定义方法

来自分类Dev

ASP.NET Identity 2-注入ISecureDataFormat <>

来自分类常见问题

Asp.NET Identity 2提供“无效令牌”错误

来自分类Dev

ASP.NET Identity 2使身份困难失效

来自分类Dev

ASP.NET Identity 2记住我-用户正在注销

来自分类Dev

ASP.NET Identity2和DataContext注入

来自分类Dev

Asp.net Identity 2帐户一次输入

Related 相关文章

  1. 1

    Asp.net Identity 2自定义用户和自定义表名称

  2. 2

    如何自定义Asp.net Identity 2用户名已采取的验证消息?

  3. 3

    自定义Asp.Net Identity 3.0

  4. 4

    ASP .NET Identity-自定义IUserStore FindByNameAsync方法

  5. 5

    如何使用 Asp.Net Identity 检查 Azure 表中是否存在记录并返回自定义响应

  6. 6

    .Net Identity 2自定义验证文本

  7. 7

    ASP.Net Identity 2 RemovePassword模拟

  8. 8

    ASP.Net Identity 2 RemovePassword模拟

  9. 9

    Asp.net Identity 2.0使用自定义唯一属性扩展UserValidator

  10. 10

    在ASP.NET Identity中为AspNetUsers表使用自定义属性

  11. 11

    ASP.NET Identity外部身份验证提供程序自定义图标

  12. 12

    自定义ASP.NET Identity(OWIN)使用实体框架的详细信息

  13. 13

    使用自定义角色在ASP.NET Identity中初始化RoleManager

  14. 14

    在ASP.NET Identity中自定义IdentityUser类时,将创建可空字段

  15. 15

    自定义MVC5 ASP.NET Identity中的cookie值

  16. 16

    使用ASP.NET Identity 2.0和MVC 5的自定义单点登录

  17. 17

    自定义MVC5 ASP.NET Identity中的cookie值

  18. 18

    将自定义列添加到ASP.NET Identity

  19. 19

    使用ASP.NET Identity 3的自定义密码策略

  20. 20

    在MVC 5中的ASP.NET Identity 3上管理自定义用户属性

  21. 21

    使用自定义 List<property> 扩展 ASP .NET Identity 并在视图中访问它

  22. 22

    如何为 Asp.Net Identity 自定义表名(例如从 AspNetUsers 更改为自定义名称)

  23. 23

    ASP.net Web API 2自定义方法

  24. 24

    ASP.NET Identity 2-注入ISecureDataFormat <>

  25. 25

    Asp.NET Identity 2提供“无效令牌”错误

  26. 26

    ASP.NET Identity 2使身份困难失效

  27. 27

    ASP.NET Identity 2记住我-用户正在注销

  28. 28

    ASP.NET Identity2和DataContext注入

  29. 29

    Asp.net Identity 2帐户一次输入

热门标签

归档