以下代码 sn-ps 提供了一种方法来检索用户通过 IdentityServer4 提供程序进行身份验证时颁发的访问令牌。为了得到
访问令牌,您可以使用 HttpContext 对象,但由于 Blazor 是基于 SignalR 的,因此您必须在 HttpContext 对象唯一可用时执行此操作,此时与应用程序的连接是 HTTP 连接,而不是 WebSocket 连接。
检索访问令牌后,您需要将其传递给您的 Blazor 应用,并将其存储在本地存储中。如果需要,我的代码还提供了一种解析访问令牌的方法。
将文件添加到 Pages 文件夹并将其命名为 _Host.cshtml.cs
-
将此代码添加到文件中:
public class HostAuthenticationModel : PageModel
{
public async Task<IActionResult> OnGet()
{
if (User.Identity.IsAuthenticated)
{
var token = await HttpContext.GetTokenAsync("access_token");
AccessToken = token;
}
return Page();
}
public string AccessToken { get; set; }
}
注意:我将 PageModel 类命名为:HostAuthenticationModel
您将需要其中一些:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System;
using System.Linq;
using System.Threading.Tasks;
- 接下来,我们必须将存储在 AccessToken 属性中的值传递给 Blazor 应用程序:
在 _Host.cshtml 文件中,在文件顶部添加模型指令:
@model HostAuthenticationModel
像这样向组件 Tag Helper 添加一个新属性:
param-AccessToken="Model.AccessToken"
最终结果:
<app>
<component type="typeof(App)" render-mode="ServerPrerendered"
param-AccessToken="Model.AccessToken"/>
</app>
param-AccessToken 属性要求您在 App 组件 中定义一个名为 AccessToken 的属性,该属性将从页面模型中获取访问令牌。
- 接下来定义将接收访问令牌的属性
-
然后重写我们从中调用方法的 OnAfterRenderAsync 方法
将访问令牌存储在本地存储中。
@code{
[Parameter]
public string AccessToken { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await tokenStorage.SetTokenAsync(AccessToken);
}
}
}
还将以下内容放在 App 组件的顶部:
@inject AccessTokenStorage tokenStorage
-
接下来,您必须像这样创建 AccessTokenStorage 服务:
在应用的根目录创建一个名为 AccessTokenStorage 的类,并添加
以下代码:
公共类AccessTokenStorage
{
私有只读 IJSRuntime _jsRuntime;
public AccessTokenStorage(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
public async Task<string> GetTokenAsync()
=> await _jsRuntime.InvokeAsync<string>("localStorage.getItem", "accessToken");
public async Task SetTokenAsync(string token)
{
if (token == null)
{
await _jsRuntime.InvokeAsync<object>("localStorage.removeItem",
"accessToken");
}
else
{
await _jsRuntime.InvokeAsync<object>("localStorage.setItem",
"accessToken", token);
}
}
}
我想这里不需要解释...这里有一些您可能需要的 using 指令
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.JSInterop;
将以下内容添加到 Startup.ConfigureServices
services.AddHttpClient();
services.AddScoped<AccessTokenStorage>();
注意:以上代码需配合我提供的代码in my answer here使用