我有一个 Blazor WASM 应用程序,通过 Open ID Connect 与我的 IdP 集成。我们需要存储在 ID 令牌和身份验证令牌中的自定义声明。这在大多数情况下都运行良好。然而,在一些预期的情况下,特定进程将更新这些数据的源数据,因此令牌中的数据已经过时。因此,在应用程序中,我想强制从 IdP 刷新这些令牌,以便它们拥有最新信息。
我尝试过寻找解决办法,但没有成功。然而,我的谷歌一定是关闭的,因为我还没有找到任何东西,甚至给我指出了正确的方向。
如果相关,我正在使用 .Net 8,我的 IdP 是 Auth0。
有人指点一下吗?
这个小黑客可能会满足您的要求。您只需清除以下会话存储并重新登录即可。并且刷新登录不会让用户再次输入用户名和密码。因为 Auth0 会话并没有真正结束。
您可以尝试以下示例。
创建 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