首页 文章

使用JWT在Asp.net Web API上实现身份验证

提问于
浏览
56

我一直在读JWT .

但从我读到的内容来看,它不是一种身份验证机制,而更像是身份验证机制中的一个关键组件 .

我目前已经实现了一个有效的解决方案,但它只是试用JWT并看看它是如何工作的 . 但我现在所追求的是如何利用它 . 根据我的经验,它基本上只是一种加密机制,可以为您提供唯一的加密密钥 . 您还可以将信息放在此令牌内 .

我希望在ASP.NET web api 2上实现它以供移动应用程序使用 .

所以第1步:

  • app =>服务器:登录(用户,密码)

  • Server => app:登录OK,继承你的JWT

  • app => server:获取我的 Profiles (发送带请求的JWT)服务器然后解密JWT并确定请求身份 .

现在这只是我对它的理解,看起来我可能走在完全错误的道路上 .

是JWT的理想选择,以便您不必在每次请求时进行身份验证吗?我只是验证用户凭证一次(在初始登录时),然后服务器可以简单地使用JWT,而不必在数据库中查找用户pw和用户?

我只想使用JWT来识别用户身份 . 然后,在我对它们进行身份验证后,我将授权 . 据我所知,新的MVC和身份验证和授权存在很大的混淆 .

那么我的问题归结为什么 .

如何使用JWT安全有效地实施身份验证机制?我不想只是咳嗽似乎有用的东西而且没有任何关于安全隐患的想法 . 我确信存在一些可能设计出符合我要求的安全机制的源 .

我的要求是:

  • 必须每次会话一次关闭数据库的用户凭据吗?由于使用bcrypt使用大量资源来比较密码 .

  • 必须能够从他们的请求中识别用户 . (即他们是谁,userId就足够了),最好不要访问数据库

  • 关于处理请求的服务器端资源,应尽可能降低开销 .

  • 如果入侵者必须复制设备先前的请求,那么他应该无法访问真实用户数据 . (明显)

谢谢

2 回答

  • 55

    您对JWT的理解很好 . 但这里有一些修改和一些建议 .

    身份验证和授权

    • JWT与身份验证无关 . 只有在创建JWT时进行身份验证时,才会触发数据库和散列密码 . 这与JWT正交,你可以用你喜欢的任何方式做到这一点 . 我个人喜欢Membership Reboot,它也有一个使用JWT的好例子 .

    • 理论上,您可以让用户每年输入一次密码,让JWT在整年内有效 . 这很可能不是最好的解决方案,如果JWT在任何时候被盗,用户资源就会受到损害 .

    加密

    • 令牌可以,但不必加密 . 加密令牌会增加系统的复杂性和服务器读取JWT所需的计算量 . 如果您要求在休息时没有人能够读取令牌,这可能很重要 .

    • 代币始终由发行人以加密方式签名,以确保其完整性 . 意味着他们不能被用户或第三方篡改 .

    索赔

    您的JWT可以包含您想要的任何信息 . 用户名,生日,电子邮件等 . 您可以使用基于声明的授权执行此操作 . 然后,您只需告知您的提供商使用声明原则中的这些声明制作JWT . 以下代码来自该成员重新启动示例,它向您展示了如何完成此操作 .

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var svc = context.OwinContext.Environment.GetUserAccountService<UserAccount>();
        UserAccount user;
        if (svc.Authenticate("users", context.UserName, context.Password, out user))
        {
            var claims = user.GetAllClaims();
    
            var id = new System.Security.Claims.ClaimsIdentity(claims, "MembershipReboot");
            context.Validated(id);
        }
    
        return base.GrantResourceOwnerCredentials(context);
    }
    

    这使您可以精确控制访问资源的人员,而无需访问处理器密集型身份验证服务 .

    实施

    实现令牌提供程序的一种非常简单的方法是在WebAPI项目中使用Microsoft's OAuth Authorization Server . 它为您提供了为API创建OAuth服务器所需的功能 .

    您还可以查看Thinktecture的Identity Server,它可以让您更轻松地控制用户 . 例如,您可以轻松地使用身份服务器实现刷新令牌,其中用户经过一次身份验证,然后在一定时间内(可能是一个月)他们可以继续获取来自Identity Server的短期JWT . 刷新令牌很好,因为它们可以被撤销,而JWT则不能 . 此解决方案的缺点是您需要设置另一台或两台服务器来托管Identity服务 .

    为了处理你的最后一点,入侵者不应该能够复制最后一个请求来访问资源,这将保护传输中的令牌 .

    如果您要保护极其敏感的内容,则应将令牌生命周期保持在非常短的时间窗口内 . 如果您要保护敏感度较低的东西,可以延长使用寿命 . 如果有效,则令牌越长,攻击者在用户的计算机受到威胁时必须模拟经过身份验证的用户的时间窗口越长 .

  • 23

    我写了一篇关于配置OWIN授权服务器以发布签名的JSON Web令牌而不是默认令牌的详细博客文章 . 因此资源服务器(Audience)可以向授权服务器注册,然后他们可以使用令牌发行方发布的JWT令牌,而无需统一各方之间的machineKey值 . 你可以阅读帖子JSON Web Token in ASP.NET Web API 2 using Owin

相关问题