在不需要的 OIDC 授权上禁用 Blazor "Authorizing" 启动画面

Disable Blazor "Authorizing" splash screen on OIDC authorization where not needed

我有一个 blazor wasm 应用程序,它通过 IdentityServer4 通过 oidc 进行预呈现和身份验证。我几乎已经设置好了,一切看起来都很好。我遇到的问题是来自 Microsoft.AspNetCore.Components.WebAssembly.Authentication 的 oidc 包似乎有一个我无法禁用的强制性“授权”启动画面。在不需要身份验证的页面上进行预呈现意味着用户将看到页面上的数据,然后在一两秒后它将被全屏身份验证屏幕取代,然后页面上的数据将返回。这方面的用户体验太糟糕了,我想我一定是设置有误,这不是它唯一的工作方式,但对于我来说,我无法靠自己或通过 google 找到解决方案。 ..

App.razor

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    <p>Not authorized.</p>
                </NotAuthorized>
                <Authorizing>
                    <p>Authorizing</p>
                </Authorizing>
            </AuthorizeRouteView>
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

这里的问题是我不能简单地删除授权标签。如果我这样做,无论如何都会显示默认页面。如果我能让它只在页面具有“@attribute [Authorize]”属性或至少没有“@attribute [AllowAnonymous]”属性时显示启动画面,我真的很喜欢它。

我是否运行遇到了包的限制?

感谢您对此的任何指导。

也可能有用,但可能没有用。服务是这样设置的。

builder.Services.AddOidcAuthentication<RemoteAuthenticationState, MyRemoteUserAccount>(options =>
{
    builder.Configuration.Bind("OidcProviderOptions", options.ProviderOptions);

    options.UserOptions.ScopeClaim = JwtClaimTypes.Scope;
    options.UserOptions.RoleClaim = JwtClaimTypes.Role;
})
.AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, MyRemoteUserAccount, MyUserFactory>();

好的,我想我已经想出了一个可以接受的解决方案。这有点繁琐,但完成了工作。

我放弃了在根级别显示身份验证状态的任何尝试。

我的 App.razor 现在看起来像这样

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

然后在应用程序的根模板中我有这样的东西

@if(AllowAnonymous)
{
    @RootBody
}
else
{
    <AuthorizeView>
        <NotAuthorized>
            <p>Not authorized to read page contents.</p>
        </NotAuthorized>
        <Authorizing>
            <p>Authorizing.</p>
        </Authorizing>
        <Authorized>
            @RootBody
        </Authorized>
    </AuthorizeView>
}

如果我需要禁用身份验证状态,我将 AllowAnonymous=true 传递给组件。我想最终根据父页面的授权属性自动执行此操作,但这目前有效。

我想你会在另一个话题中找到你正在寻找的答案

我也去搜索只是为了发现解决方案是多么简单:

<MudThemeProvider/>
<MudDialogProvider/>
<MudSnackbarProvider/>
<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <Authorizing>
                    @* YOUR CODE HERE *@
                </Authorizing>
                <NotAuthorized>
                    @if (!context.User.Identity.IsAuthenticated)
                    {
                        <RedirectToLogin />
                    }
                    else
                    {
                        <p>You know, I have no idea how you got here but this is not a place I let people into!</p>
                    }
                </NotAuthorized>
            </AuthorizeRouteView>
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address, well, yet anyway!</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>