在带有 Open ID Connect 的 Blazor WASM 中,如何强制刷新 Auth/ID 令牌

问题描述 投票:0回答:1

我有一个 Blazor WASM 应用程序,通过 Open ID Connect 与我的 IdP 集成。我们需要存储在 ID 令牌和身份验证令牌中的自定义声明。这在大多数情况下都运行良好。然而,在一些预期的情况下,特定进程将更新这些数据的源数据,因此令牌中的数据已经过时。因此,在应用程序中,我想强制从 IdP 刷新这些令牌,以便它们拥有最新信息。

我尝试过寻找解决办法,但没有成功。然而,我的谷歌一定是关闭的,因为我还没有找到任何东西,甚至给我指出了正确的方向。

如果相关,我正在使用 .Net 8,我的 IdP 是 Auth0。

有人指点一下吗?

asp.net-core blazor openid-connect blazor-webassembly auth0
1个回答
0
投票

这个小黑客可能会满足您的要求。您只需清除以下会话存储并重新登录即可。并且刷新登录不会让用户再次输入用户名和密码。因为 Auth0 会话并没有真正结束。
enter image description here

您可以尝试以下示例。
创建 WASM 独立项目添加包

Microsoft.AspNetCore.Components.WebAssembly.Authentication

在wwwroot文件夹中创建

MyScript.js

function remove_session(prefix) {

    for (let i = 0; i < sessionStorage.length; i++) {
        const key = sessionStorage.key(i);

        if (key.startsWith(prefix)) {
            sessionStorage.removeItem(key);
        }
    }
}

Index.cshtml 添加以下内容(该包需要此 js 互操作)

<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>

程序.cs

builder.Services.AddCascadingAuthenticationState();

builder.Services.AddOidcAuthentication(options =>
{
   
    options.ProviderOptions.Authority = "https://xxx.auth0.com"; 
    options.ProviderOptions.ClientId = "xxx";           
    options.ProviderOptions.ResponseType = "code";           
    options.ProviderOptions.DefaultScopes.Add("openid");
    options.ProviderOptions.DefaultScopes.Add("profile");
    //options.ProviderOptions.DefaultScopes.Add("offline_access");   this will give you a refreshToken, but this sample doesn't need
    options.ProviderOptions.RedirectUri = "https://localhost:7056/authentication/login-callback";
    options.ProviderOptions.PostLogoutRedirectUri = "https://localhost:7056/authentication/logout-callback";  
});

添加

Authentication.razor

@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="@Action"></RemoteAuthenticatorView>
@code {
    [Parameter] public string? Action { get; set; }
}

Home.剃须刀

@page "/"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject IJSRuntime js
@inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager

<AuthorizeView>
    <Authorized>
        <p>Welcome, @context.User.Identity.Name</p>
        <button @onclick="RefreshAuth">Refresh</button>
        <button @onclick="Logout">Logout</button>
    </Authorized>
    <NotAuthorized>
        <button @onclick="Login">Login</button>
    </NotAuthorized>
</AuthorizeView>

@code {

    private async void Login()
    {
        Navigation.NavigateTo("authentication/login");
    }

    private async Task Logout()
    {
        await SignOutManager.SetSignOutState();
        Navigation.NavigateTo("authentication/logout");
    }

    private async Task RefreshAuth()
    {
        await js.InvokeVoidAsync("remove_session","oidc");
        Login();        

    }
}

测试:点击“登录”即可显示用户名。然后您在Auth0管理控制台中更改用户名。点击刷新,用户名就会变成新的。

此外,如果您使用刷新令牌。您可以使用

IAccessTokenProvider
获取包含新用户信息的新
accessToken/IdToken

        var result = await TokenProvider.RequestAccessToken(new AccessTokenRequestOptions
            {
                Scopes = new[] { "abc" }, // just use a scope that doesn't exist
            });

但问题是

AuthenticationStateProvider
将在WASM中使用
RemoteAuthenticationService
。它使用 jsinterop
AuthenticationService.getUser()
来获取用户主体。但是这个 javascript 函数无法从 IdToken 获取新用户。我认为这里需要解决一些问题。 https://stackoverflow.com/a/75472254/20240963

© www.soinside.com 2019 - 2024. All rights reserved.