首页 > 解决方案 > 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;
            }
        }
    }

标签: authenticationoauth-2.0blazor-webassemblyokta

解决方案


推荐阅读