保护 ASP.NET Core Blazor WebAssemblySecure ASP.NET Core Blazor WebAssembly
重要
Blazor WebAssembly 为预览版状态
ASP.NET Core 3.0 支持 Blazor Server。Blazor WebAssembly 在 ASP.NET Core 3.1 中为预览版。
备注
本文中的指导适用于 ASP.NET Core Blazor WebAssembly 模板 3.2 版或更高版本。要在未使用 Visual Studio 版本 16.6 预览版 2 或更高版本时获取最新的 Blazor WebAssembly 模板(版本 ),请参阅 。
Blazor WebAssembly 应用与单页应用程序 (SPA) 的保护方式相同。可通过多种方式向 SPA 进行用户身份验证,但最常用、最全面的方式是使用基于 oAuth 2.0 协议的实现,例如 。
Blazor WebAssembly 中的身份验证支持建立在 oidc-client.js 库的基础之上,该库用于处理底层身份验证协议详细信息。
还有对 SPA 进行身份验证的其他选项,例如使用 SameSite cookie。但是,Blazor WebAssembly 的工程设计决定,oAuth 和 OIDC 是在 Blazor WebAssembly 应用中进行身份验证的最佳选择。出于以下功能和安全原因,选择了以 JSON Web 令牌 (JWT) 为基础的而不是基于 cookie 的身份验证:
- 使用基于令牌的协议可以减小攻击面,因为并非所有请求中都会发送令牌。
- 令牌的权限比 cookie 窄。例如,令牌不能用于管理用户帐户或更改用户密码,除非显式实现了此类功能。
- 令牌的生命周期更短(默认为一小时),这限制了攻击时间窗口。还可随时撤销令牌。
- 自包含 JWT 向客户端和服务器提供身份验证进程保证。例如,客户端可以检测和验证它收到的令牌是否合法,以及是否是在给定身份验证过程中发出的。如果有第三方尝试在身份验证进程中偷换令牌,客户端可以检测被偷换的令牌并避免使用它。
- oAuth 和 OIDC 的令牌不依赖于用户代理行为正确以确保应用安全。
- 基于令牌的协议(例如 oAuth 和 OIDC)允许用同一组安全特征对托管和独立应用进行验证和授权。
库提供几个基元,用于实现使用 OIDC 的身份验证和授权。从广义上说来,身份验证的原理如下:
- 当匿名用户选择登录按钮或请求应用了 特性的页面时,会将其重定向到应用的登录页 ()。
- 在登录页上,身份验证库准备重定向到授权终结点。授权终结点在 Blazor WebAssembly 应用外部,可托管在独立的源。该终结点负责确定用户是否通过身份验证,并发送一个或更多令牌作为响应。身份验证库提供登录回叫以接收身份验证响应。
- 如果用户未通过身份验证,会将其重定向到底层身份验证系统,通常是 ASP.NET Core 标识。
- 如果用户已通过身份验证,则授权终结点会生成相应的令牌,并将浏览器重定向回登录回叫终结点 (
/authentication/login-callback
)。
使用第三方提供程序对托管的 Blazor WebAssembly 应用进行身份验证和授权时,有几个选项可用于对用户进行身份验证。选择哪一种选项取决于方案。
有关详细信息,请参阅 在 ASP.NET Core 中保存外部提供程序的其他声明和令牌。
使用针对第三方 API 提供程序的客户端 oAuth 流对用户进行身份验证:
- 托管应用的服务器不会发挥作用。
- 无法保护服务器上的 API。
- 应用只能调用受保护的第三方 API。
使用第三方登录提供程序配置标识。获取第三方 API 访问所需的令牌并进行存储。
当用户登录时,标识将在身份验证过程中收集访问和刷新令牌。此时,可通过几种方法向第三方 API 进行 API 调用。
使用服务器访问令牌检索第三方访问令牌Use a server access token to retrieve the third-party access token
使用服务器上生成的访问令牌从服务器 API 终结点检索第三方访问令牌。在此处,使用第三方访问令牌直接从客户端上的标识调用第三方 API 资源。
我们不建议使用此方法。此方法需要将第三方访问令牌视为针对公共客户端生成。在 oAuth 范畴,公共应用没有客户端机密,因为不能信任此类应用来安全地存储机密,并且访问令牌是为机密客户端而生成的。机密客户端具有客户端机密,并且假定能够安全地存储机密。
- 第三方访问令牌可能会被授予其他作用域,以便基于第三方为更受信任的客户端发出令牌的情况执行敏感操作。
- 同样,不应向不受信任的客户端颁发刷新令牌,因为这样做会给客户端提供无限制的访问权限,除非存在其他限制。
从客户端向服务器 API 发出 API 调用以便调用第三方 APIMake API calls from the client to the server API in order to call third-party APIs
从客户端向服务器 API 发出 API 调用。从服务器中检索第三方 API 资源的访问令牌,并发出任何所需调用。
尽管此方法需要额外的网络跃点通过服务器来调用第三方 API,但最终可提供更安全的体验:
- 服务器可以存储刷新令牌,并确保应用不会失去对第三方资源的访问权限。
- 应用无法从服务器泄漏可能包含更多敏感权限的访问令牌。