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

时间:2014-05-15 09:42:59

标签: asp.net-web-api authentication jwt

我一直在读JWT。

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

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

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

所以第1步:

  1. app =>服务器:登录(用户,密码)
  2. 服务器=> app:登录OK,继承你的JWT
  3. app =>服务器:获取我的个人资料(发送带有请求的JWT)  然后,服务器解密JWT并确定请求身份。
  4. 现在这只是我对它的理解,看起来我可能走错了路。

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

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

    所以我的问题归结为。

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

    我的要求是:

    • 每次会话只需要一次性检查db for users凭据吗?由于使用bcrypt使用大量资源来比较密码。
    • 必须能够根据他们的请求识别用户。 (即他们是谁,userId就足够了),最好不要访问数据库
    • 对于处理请求的服务器端资源,应尽可能降低开销。
    • 如果入侵者必须复制设备之前的请求,那么他应该无法访问真实用户数据。 (显然)

    由于

3 个答案:

答案 0 :(得分: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服务。

为了处理您的最后一点,入侵者无法复制最后一个请求以访问资源,您必须至少使用SSL。这将保护令牌在运输中。

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

答案 1 :(得分:23)

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

答案 2 :(得分:0)

对于正式概念。身份验证是验证用户身份的过程,而授权是验证用户有权访问的过程。

让我们看看现实生活中的例子

想象一下,您的邻居要您在他不在时喂他的宠物。在此示例中,您有权访问厨房并打开存储宠物食品的橱柜。但是,您不能进入邻居的卧室,因为他没有明确允许您这样做。即使您有权进入房屋(通过身份验证),您的邻居也只允许您进入某些区域(授权)。

针对更详细的信息以及喜欢在Web API中实际使用JSON Web令牌 STEP BY STEP实现的用户。这是必读文章Secure WebAPI Using JSON WEB TOKEN

已更新为使用:System.IdentityModel.Tokens.Jwt-版本5.1.4