如何在 C# AspNetCore 网站中使用 JWT JSON Web 令牌?

Posted

技术标签:

【中文标题】如何在 C# AspNetCore 网站中使用 JWT JSON Web 令牌?【英文标题】:How to use JWT JSON Web Tokens in C# AspNetCore Websites? 【发布时间】:2018-01-09 20:53:15 【问题描述】:

我正在尝试整合一个使用 JWT 进行登录的网站。我的问题是我不明白网站应该如何使用 JWT。

这个想法是将我的单体架构拆分为:

用于身份验证和发布 JWT 的 IdentityServer。 一个 ApplicationServer API,其端点受基于 JWT 的角色保护。 从 IdentityServer 请求 JWT 并使用它们访问 ApplicationServer 上的数据的前端应用程序和网站。

这将允许我将一个 IdentityServer 用于多个项目,并可能将前端开发外包给第 3 方,并允许我专注于应用程序 API 细节。

我已经构建了 IdentityServer。它可以获取用户名/密码、验证并发出访问令牌和刷新令牌。极好的。 访问令牌是短暂且不安全的,并且旨在定期刷新。目的是将其存储在客户端,无论是应用程序还是网页。 刷新令牌的寿命更长,并且旨在安全地存储。在网站上,这将存储在服务器端,在应用程序中,在“会话”期间存储在安全存储中。

我有一个前端网站外壳设置了一些测试操作。用户必须经过身份验证才能访问它们,其中经过身份验证意味着拥有有效的访问令牌。

当用户最初访问操作时,他们没有令牌。 前端网络服务器应将它们重定向到登录页面,并请求凭据(用户名和密码)。 Web 服务器将凭据转发给 IdentityServer,如果凭据有效,IdentityServer 应将访问和刷新令牌返回给 Web 服务器。 网络服务器将缓存刷新令牌并将访问令牌发送回网页。 然后,客户端网页会缓存访问令牌,并将其与每个进一步的页面请求一起发送。 网络服务器将对访问令牌进行解码,如有必要,可能会对其进行刷新,然后将带有更新后的访问令牌的页面发回。 会话(会话)在带有陈旧访问令牌的请求进入并且刷新令牌过期的足够时间后结束,并且用户被重定向到登录页面。

对于如何将访问令牌返回到网页,我有点迷茫。

另外,我不明白网页如何自动为每个请求附加一个令牌(如果有),或者网页如何响应 401 质询(如果没有)。

cookie 是将数据附加到 HTTP 会话并在导航期间将其持久保存在客户端的唯一方法吗?

JWT 是否纯粹用于 SinglePageApps (SPA),其中最初提供页面,然后所有后续数据都由 Ajax 处理(我可以在其中设置标题没有问题)?

或者,是否可以编写网页,使其始终使用访问令牌填充授权标头(如果存在)?

我意识到我可能认为自己陷入困境,任何帮助将不胜感激。

【问题讨论】:

我相信您的令牌应该存储在网络请求标头中。由于它在每个请求中,它都允许挑战。在每次通话时,验证访问权限。而不是 cookie,虽然它是一个选项。 是的,我不明白的是如何从客户端获取每个请求以包含授权标头。 为什么不能在每个请求中手动添加带有授权、承载和提供的令牌值的标头? request.Headers.Add("authorization", $"bearer=token");。类似的东西? 这是在客户端的 javascript 中吗?客户端如何知道填充此标头?抱歉,如果我是愚蠢的。如果应用程序正在配置 Http 请求,或者请求是 Ajax,我完全明白这是如何工作的,但是如果用户输入 URL 或通过链接导航到另一个页面,请求如何包含标头?我猜只有 cookie 会这样做,但我认为 JWT 会取代 cookie。 那是一种 C# 风格的方法,但是从 Ajax 或 Axios 中,您可以操作标头:$.ajax( headers: 'authorization', 'bearer=' + token);。会沿着这些路线。 【参考方案1】:

您应该阅读 Auth0 的 Resource Owners Password Grant https://auth0.com/docs/api-auth/grant/password

文档

我会将刷新令牌和访问令牌一起保存在客户端上。

我的方法是。

客户端知道它没有访问令牌 -> 显示登录按钮。 单击登录按钮-> 使用登录页面重定向到身份验证服务器。它包括一个状态/代码和一个回调 url。 客户端接收到用户的回调,并将其视为客户端登录。 客户端将访问令牌和刷新令牌(如果提供)存储在本地存储中。 然后它将访问令牌传递给它想要访问的 api 的请求。 API 检查访问令牌是否适用于它并且有效,允许授权并完成请求。 API 对刷新令牌一无所知。

希望对你有帮助

【讨论】:

我现在已经实现了这个并且学到了更多。我将刷新令牌保存在服务器上的 RAM 查找缓存中。我将客户端上的访问令牌保存在 cookie 中。所有请求都会检查 cookie 中的访问令牌,如果是陈旧的,则刷新令牌用于获取新的访问令牌(如果刷新令牌陈旧,则再次登录)。然后客户端可以访问其他操作或页面并拥有 cookie,但不会公开刷新令牌。访问令牌绑定到 IP 地址和用户代理。 Cookie 是 HTTPOnly,HTTPS 的一切。

以上是关于如何在 C# AspNetCore 网站中使用 JWT JSON Web 令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何在发布文件中设置 aspnetcore_environment?

如何在非控制器类中从 Microsoft.AspNetCore.Identity 获取 UserID

如何使用 agsXMPP c# 创建 jabber 帐户?

C# Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] 执行请求时发生未处理的异常

C# Blazor WebAssembly:参数 2:无法从“void”转换为“Microsoft.AspNetCore.Components.EventCallback”

Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT 中间件 C# .NET Core 2.2