authentication - Blazor WASM AuthorizeView 在身份验证过期后显示用户已通过身份验证
问题描述
我有一个使用 Okta 的 Blazor WASM 应用程序具有第三方身份验证器。我根据 Okta 提供的 YouTube 视频创建了该应用程序:Build Auth FAST for Blazor WebAssembly in .NET。根据该教程,我添加了一个 Claims.razor 页面来测试身份验证。当应用程序启动并导航到声明页面时,我被重定向到 Okta 登录页面。成功登录后,我将返回到 Claims 页面,并且 context.User 已正确填充。这一切都按预期工作。但是,如果我等到用户登录过期,我仍然可以导航到“声明”页面,它将显示已通过身份验证的用户的声明。
我预计 AuthenticationStateProvider 会检测到登录已过期并导致重定向到登录页面,但事实并非如此。
用户身份验证过期后如何强制重定向到登录?
我的 Claims.razor 页面:
@page "/claims"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Microsoft.Extensions.Configuration
@attribute [Authorize]
@inject HttpClient httpClient
@inject IConfiguration Configuration
<AuthorizeView>
<Authorized>
<h2>
Hello @context.User.Identity.Name,
here's a list of your claims:
</h2>
<ul>
@foreach (var claim in context.User.Claims)
{
<li>@claim.Type:<b>@claim.Value</b></li>
}
</ul>
<p>This component demonstrates fetching data from the server.</p>
@if (serverMessages == null)
{
<p><em>Loading...</em></p> }
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Text</th>
</tr>
</thead>
<tbody>
@foreach (var message in serverMessages.Messages)
{
<tr>
<td>@message.Date.ToShortDateString()</td>
<td>@message.Text</td>
</tr>
}
</tbody>
</table>}
</Authorized>
<NotAuthorized>
<p>Sorry you must login first.</p>
</NotAuthorized>
</AuthorizeView>
@code {
private ServerMessages serverMessages;
protected override async Task OnInitializedAsync()
{
try
{
serverMessages = await httpClient.GetFromJsonAsync<ServerMessages>(Configuration["ServerApi:MessagesEndpoint"]);
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
}
public class ServerMessage
{
public DateTime Date { get; set; }
public string Text { get; set; }
}
public class ServerMessages
{
public IList<ServerMessage> Messages { get; set; }
}
}
根据评论更新:
上面提到的AuthenticationStateProvider
是微软提供的默认值。以下是将访问令牌添加到 http 请求的自定义消息处理程序的代码:
class AuthHeaderHandler : DelegatingHandler
{
private IAccessTokenProvider _accessTokenProvider;
public AuthHeaderHandler(IAccessTokenProvider accessTokenProvider)
{
this._accessTokenProvider = accessTokenProvider ?? throw new ArgumentNullException(nameof(accessTokenProvider));
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
try
{
var token = await _accessTokenProvider.RequestAccessToken();
var t = token.TryGetToken(out AccessToken accessToken);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken?.Value ?? string.Empty);
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
catch(Exception ex)
{
throw;
}
}
}
解决方案
推荐阅读
- visual-studio - Xamarin android .axml 文件加载错误:该项目不支持预览
- vim - Easy Vim 的单独设置(带有 -y 标志)
- javascript - 嵌套 if 语句与 &&(or) 运算符
- c# - 尝试使用 httpwebrequest 从 SSL 网站获取数据时出现超时?
- ruby-on-rails - 如何使我的多态模型工作?
- reactjs - 这是 Flux 架构吗?
- excel - Excel 动态地将字段添加到行范围
- swift - 将关于录制麦克风信号的旧 swift 代码行翻译为 swift 4.2
- django - 返回指向django中其他对象的对象
- c# - 为什么 Azure WebJob 无法连接到 Azure SQL,说“存储帐户的类型不受支持‘Blob-Only/ZRS’。支持的类型是‘通用’?