【问题标题】:Using JWT to implement Authentication on Asp.net web API使用 JWT 在 Asp.net Web API 上实现身份验证
【发布时间】:2014-07-03 16:28:54
【问题描述】:

我一直在阅读有关 JWT 的文章。

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

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

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

所以第 1 步:

  1. app => 服务器:登录(用户,密码)
  2. 服务器 => 应用程序:登录 OK,这是您的 JWT
  3. app => server : 获取我的个人资料(发送带有请求的 JWT) 然后服务器解密 JWT 并确定请求的身份。

现在这只是我的理解,看我可能走错了路。

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

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

所以我的问题归结为。

如何使用 JWT 安全有效地实现身份验证机制? 我不想只是咳出一些似乎有效的东西,而且对安全隐患没有任何想法。我确信有一个来源可能设计了一个适合我要求的安全机制。

我的要求是:

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

谢谢

【问题讨论】:

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


【解决方案1】:

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

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

如果您要保护一些极其敏感的东西,您应该将令牌的生命周期保持在一个非常短的时间窗口内。如果您保护的是不那么敏感的东西,您可以延长使用寿命。如果令牌有效,则令牌越长,如果用户的计算机受到威胁,攻击者将不得不冒充已验证用户的时间窗口就越大。

【讨论】:

  • 非常感谢,您提供的信息非常丰富。所以基本上 JWT 的安全性归结为 SSL 保护它。其加密的事实仅仅是因为您不想在客户端以纯文本形式保存声明。
  • 我是这么理解的,但我不是专家。如果用户机器被黑客入侵,那么无论加密如何,JWT 都不会为您的服务提供保护。这个book 是一个很好的资源,我从中学到了大部分信息。另外,这个pluralsight course也很有帮助。
  • 这是一个很好的答案。作为旁注,我们一直在尝试实现 JWE(加密的 JWT)。似乎框架允许使用自定义编码类型,但不尊重令牌验证的自定义类型......
【解决方案2】:

我已经写了关于配置 OWIN 授权服务器以发出签名 JSON Web 令牌而不是默认令牌的详细博客文章。所以资源服务器(Audience)可以注册到Authorization server,然后就可以使用Token发行方发行的JWT令牌,而无需在各方之间统一machineKey值。您可以阅读帖子JSON Web Token in ASP.NET Web API 2 using Owin

【讨论】:

  • 这个链接对我很有帮助。
  • 帮助很大,是的。但是我对确定 JwtSecurityToken 参数的 issuer 参数有点困惑。确实,我在这里有一个问题:stackoverflow.com/q/41090102/4636715 例如,如果我们将其保留为空怎么办?是否以授权服务器本身为宿主?
【解决方案3】:

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

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

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

对于更详细的和喜欢更多逐步实现在WEB API中实际使用JSON Web Token的用户。这是必须阅读的帖子Secure WebAPI Using JSON WEB TOKEN

更新为使用:System.IdentityModel.Tokens.Jwt -Version 5.1.4

【讨论】:

    猜你喜欢
    • 2017-07-30
    • 2017-03-09
    • 1970-01-01
    • 2018-01-28
    • 2018-10-27
    • 2019-09-03
    相关资源
    最近更新 更多