如何从 blazor(服务器端)网络应用程序获取访问令牌?
How do I get the access token from a blazor (server-side) web app?
实现openidconnect后,blazor将access token存放在哪里?如何取回?
以下代码片段提供了一种方法来检索用户使用 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 命名为 class: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 的 class,并添加
以下代码:
public class 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>();
注意:以上代码要和我提供的代码一起使用
我用的是下面的方式
Startup.cs
services.AddHttpContextAccessor();
剃刀页面
@using Microsoft.AspNetCore.Http
@using Microsoft.AspNetCore.Authentication
@inject IHttpContextAccessor httpContextAccessor
@code {
private async Task<string> GetToken()
=> await httpContextAccessor.HttpContext.GetTokenAsync("access_token");
}
我通过添加下面 link 中列出的代码解决了这个问题。
注意:上面link中列出的步骤工作正常,但是,我做了一些对我来说更有意义的小修改。我还修改了对我来说更有意义的顺序。
步骤:
1.创建 TokenProvider class
public class TokenProvider
{
public string AccessToken { get; set; }
}
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>
3。用 DI 更新 StartUp.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddScoped<TokenProvider>();
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();
}
}
5.在构造函数中创建 _tokenProvider 的实例
并用它来获取访问令牌
注意: 下面我得到的访问令牌不在 @code 块或 Blazor 页面的代码后面,但我使用的是服务 class。 (页面调用服务class)。我希望这是有道理的。同样,我建议您查看上面的 link。
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);
}
希望以上步骤对其他人有所帮助。
实现openidconnect后,blazor将access token存放在哪里?如何取回?
以下代码片段提供了一种方法来检索用户使用 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 命名为 class: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 的 class,并添加 以下代码:
public class 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>();
注意:以上代码要和我提供的代码一起使用
我用的是下面的方式
Startup.cs
services.AddHttpContextAccessor();
剃刀页面
@using Microsoft.AspNetCore.Http
@using Microsoft.AspNetCore.Authentication
@inject IHttpContextAccessor httpContextAccessor
@code {
private async Task<string> GetToken()
=> await httpContextAccessor.HttpContext.GetTokenAsync("access_token");
}
我通过添加下面 link 中列出的代码解决了这个问题。
注意:上面link中列出的步骤工作正常,但是,我做了一些对我来说更有意义的小修改。我还修改了对我来说更有意义的顺序。
步骤:
1.创建 TokenProvider class
public class TokenProvider
{
public string AccessToken { get; set; }
}
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>
3。用 DI 更新 StartUp.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddScoped<TokenProvider>();
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();
}
}
5.在构造函数中创建 _tokenProvider 的实例 并用它来获取访问令牌
注意: 下面我得到的访问令牌不在 @code 块或 Blazor 页面的代码后面,但我使用的是服务 class。 (页面调用服务class)。我希望这是有道理的。同样,我建议您查看上面的 link。
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);
}
希望以上步骤对其他人有所帮助。