diff --git a/src/BootstrapBlazor/Components/Layout/Layout.razor b/src/BootstrapBlazor/Components/Layout/Layout.razor index bd76cfaa9b6..65fd1443dee 100644 --- a/src/BootstrapBlazor/Components/Layout/Layout.razor +++ b/src/BootstrapBlazor/Components/Layout/Layout.razor @@ -5,7 +5,7 @@ @if (_init) { - @if (IsAuthenticated) + @if (_authenticated) {
@if (Side == null) @@ -126,8 +126,8 @@ } else { - + @HandlerMain() } @@ -135,7 +135,7 @@ RenderFragment RenderTab => @ + EnableErrorLogger="@EnableLogger" ErrorLoggerToastTitle="@ErrorLoggerToastTitle"> ; RenderFragment RenderFooter => diff --git a/src/BootstrapBlazor/Components/Layout/Layout.razor.cs b/src/BootstrapBlazor/Components/Layout/Layout.razor.cs index 477057934e6..32c498f9f52 100644 --- a/src/BootstrapBlazor/Components/Layout/Layout.razor.cs +++ b/src/BootstrapBlazor/Components/Layout/Layout.razor.cs @@ -361,6 +361,12 @@ public partial class Layout : IHandlerException, ITabHeader [Parameter] public bool ShowTabInHeader { get; set; } + /// + /// 获得/设置 是否跳过认证逻辑 默认 false + /// + [Parameter] + public bool SkipAuthenticate { get; set; } + [Inject] [NotNull] private NavigationManager? Navigation { get; set; } @@ -374,7 +380,7 @@ public partial class Layout : IHandlerException, ITabHeader /// /// 获得/设置 是否已授权 /// - private bool IsAuthenticated { get; set; } + private bool _authenticated; /// /// 获得 组件样式 @@ -501,15 +507,15 @@ public partial class Layout : IHandlerException, ITabHeader private IOptionsMonitor? Options { get; set; } private bool _init; - private LayoutHeader? _layoutHeader = null; + private LayoutHeader? _layoutHeader; private ITabHeader? TabHeader => ShowTabInHeader ? this : null; - private bool _enableErrorLogger => EnableErrorLogger ?? Options.CurrentValue.EnableErrorLogger; + private bool EnableLogger => EnableErrorLogger ?? Options.CurrentValue.EnableErrorLogger; - private bool _showToast => ShowErrorLoggerToast ?? Options.CurrentValue.ShowErrorLoggerToast; + private bool ShowToast => ShowErrorLoggerToast ?? Options.CurrentValue.ShowErrorLoggerToast; - private bool _enableILogger => EnableErrorLoggerILogger ?? Options.CurrentValue.EnableErrorLoggerILogger; + private bool EnableILogger => EnableErrorLoggerILogger ?? Options.CurrentValue.EnableErrorLoggerILogger; /// /// @@ -535,30 +541,28 @@ protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - // 需要认证并且未认证 - if (AuthenticationStateTask != null) + if (SkipAuthenticate || AuthenticationStateTask == null) { - // wasm 模式下 开启权限必须提供 AdditionalAssemblies 参数 - AdditionalAssemblies ??= [Assembly.GetEntryAssembly()!]; + _authenticated = true; + _init = true; + return; + } - var url = Navigation.ToBaseRelativePathWithoutQueryAndFragment(); - var context = RouteTableFactory.Create(AdditionalAssemblies, url); - if (context.Handler != null) - { - IsAuthenticated = await context.Handler.IsAuthorizedAsync(ServiceProvider, AuthenticationStateTask, Resource); + // wasm 模式下 开启权限必须提供 AdditionalAssemblies 参数 + AdditionalAssemblies ??= [Assembly.GetEntryAssembly()!]; - // 检查当前 Url - if (OnAuthorizing != null) - { - IsAuthenticated = IsAuthenticated && await OnAuthorizing(Navigation.Uri); - } - } - } - else + var url = Navigation.ToBaseRelativePathWithoutQueryAndFragment(); + var context = RouteTableFactory.Create(AdditionalAssemblies, url); + if (context.Handler != null) { - IsAuthenticated = true; - } + _authenticated = await context.Handler.IsAuthorizedAsync(ServiceProvider, AuthenticationStateTask, Resource); + // 检查当前 Url + if (OnAuthorizing != null) + { + _authenticated = _authenticated && await OnAuthorizing(Navigation.Uri); + } + } _init = true; } diff --git a/test/UnitTest/Components/LayoutTest.cs b/test/UnitTest/Components/LayoutTest.cs index e778aa92225..72682e31423 100644 --- a/test/UnitTest/Components/LayoutTest.cs +++ b/test/UnitTest/Components/LayoutTest.cs @@ -673,6 +673,23 @@ public void CollapseBarTemplate_Ok() Assert.Contains("CollapseBarTemplate-Content", cut.Markup); } + + [Fact] + public void SkipAuthenticate_Ok() + { + // 未授权,通过控制 SkipAuthenticate 属性跳过授权 + var cut = Context.RenderComponent>>(pb => + { + pb.Add(a => a.Value, Task.FromResult(new AuthenticationState(new ClaimsPrincipal()))); + pb.AddChildContent(pb => + { + pb.Add(a => a.SkipAuthenticate, true); + pb.Add(a => a.Main, builder => builder.AddContent(0, "Main")); + }); + }); + cut.MarkupMatches("
Main
"); + } + private static RenderFragment CreateHeader(string? content = "Header") => builder => builder.AddContent(0, content); private static RenderFragment CreateFooter(string? content = "Footer") => builder => builder.AddContent(0, content);