001*_*001 1 c# asp.net blazor blazor-server-side
实现 openidconnect 后,blazor 在哪里存储访问令牌?如何找回它?
如何通过 IdentityServer4 将 OpenIdConnect 添加到 ASP.NET Core ServerSide Blazor Web 应用程序?
Ric*_*ard 12
我通过添加下面链接中列出的代码解决了这个问题。
注意:上面链接中列出的步骤工作正常,但是,我做了一些对我来说更有意义的小修改。我还修改了对我来说更有意义的顺序。
脚步:
1.创建TokenProvider类
public class TokenProvider
{
public string AccessToken { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
2. 使用以下内容更新 _Host.cshtml 文件:
@using Microsoft.AspNetCore.Authentication
@{
var accessToken = await HttpContext.GetTokenAsync("access_token");
}
<body>
<app>
<component type="typeof(App)" param-AccessToken="accessToken" render-mode="ServerPrerendered" />
</app>
Run Code Online (Sandbox Code Playgroud)
3. 使用 DI 更新 StartUp.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddScoped<TokenProvider>();
Run Code Online (Sandbox Code Playgroud)
4. 使用以下内容更新 App.razor:
@inject TokenProvider TokenProvider
@code
{
[Parameter]
public string AccessToken { get; set; }
protected override void OnInitialized()
{
//Accept the parameter from _Host.cshtml and move into the Token Provider
TokenProvider.AccessToken = AccessToken;
base.OnInitialized();
}
}
Run Code Online (Sandbox Code Playgroud)
5.在构造函数中创建_tokenProvider的实例 并使用它来获取Access Token
注意:下面我获取的访问令牌不在 @code 块或 Blazor 页面后面的代码中,但我使用的是 Service 类。(页面调用Service类)。我希望这是有道理的。我再次建议您查看上面的链接。
private readonly TokenProvider _tokenProvider;
//Create tokenProvider using constructor Dependency Injection
public HttpClientUtility(TokenProvider tokenProvider)
{
_tokenProvider = tokenProvider;
}
var accessToken = _tokenProvider.AccessToken;
if (accessToken != null)
{
_httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
}
Run Code Online (Sandbox Code Playgroud)
希望上述步骤对其他人有帮助。
以下代码片段提供了一种检索用户通过 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; }
}
Run Code Online (Sandbox Code Playgroud)注意:我将 PageModel 类命名为: HostAuthenticationModel 您将需要其中的一些:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System;
using System.Linq;
using System.Threading.Tasks;
在 _Host.cshtml 文件的顶部添加模型指令:
@model HostAuthenticationModel
Run Code Online (Sandbox Code Playgroud)
向组件 Tag Helper 添加一个新属性,如下所示:
param-AccessToken="Model.AccessToken"
Run Code Online (Sandbox Code Playgroud)
最后结果:
<app>
<component type="typeof(App)" render-mode="ServerPrerendered"
param-AccessToken="Model.AccessToken"/>
</app>
Run Code Online (Sandbox Code Playgroud)
该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);
}
}
}
Run Code Online (Sandbox Code Playgroud)还将以下内容放在 App 组件的顶部:
@inject AccessTokenStorage tokenStorage
Run Code Online (Sandbox Code Playgroud)
接下来,您必须像这样创建 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)我想这里不需要解释......这里有一些你可能需要的使用指令
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>();
注意:上面的代码应该与我在我的回答中提供的代码一起使用