【问题标题】:Blazor Authentication - Http calls does work for anonymousBlazor 身份验证 - Http 调用确实适用于匿名
【发布时间】:2021-05-23 05:54:53
【问题描述】:

我一直在使用 .net 5.0 玩 blazor。我遇到了一个简单但烦人的问题:我正在尝试从 API 加载数据,但对服务器 blazor 的每次调用都希望用户登录。

我明白如果我们从 API 控制器中取出 [Authorize] 标记并且在 razor 页面中没有 @attribute [Authorize],那就是这样。但我很难理解为什么我的 API 调用仍然需要 protected override async Task OnInitializedAsync() 中的 AccessToken 错误消息并没有说明原因。

Microsoft.AspNetCore.Components.WebAssembly.Authentication.AccessTokenNotAvailableException: ''
at Microsoft.AspNetCore.Components.WebAssembly.Authentication.AuthorizationMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)

我还没有碰过这个应用程序。 Web程序集的cs文件..

谁能帮帮我。

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    @if (!context.User.Identity.IsAuthenticated)
                    {
                        <RedirectToLogin />
                    }
                    else
                    {
                        <p>You are not authorized to access this resource.</p>
                    }
                </NotAuthorized>
                <Authorizing>
                    <h4>Authentication in progress...</h4>
                </Authorizing>                
            </AuthorizeRouteView>
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

【问题讨论】:

  • 能否将您的应用上传到 github...

标签: asp.net-core blazor forms-authentication blazor-webassembly blazor-client-side


【解决方案1】:

我认为这是因为 CascadingAuthenticationState 封装了 Foundcontext 和 NotFound,因为它的作用是将授权信息传递给其他组件。因此,将它包裹在所有组件周围可以防止未经授权的用户访问。试试这个

<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
    <Found Context="routeData">
        <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
            <NotAuthorized>
                @if (!context.User.Identity.IsAuthenticated)
                {
                    <RedirectToLogin />
                }
                else
                {
                    <p>You are not authorized to access this resource.</p>
                }
            </NotAuthorized>
            <Authorizing>
                <h4>Authentication in progress...</h4>
            </Authorizing>                
        </AuthorizeRouteView>
    </Found>
    <NotFound>
        <CascadingAuthenticationState>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        <CascadingAuthenticationState>
    </NotFound>
</Router>

【讨论】:

    【解决方案2】:

    我想出了解决方案……应该先看看它。

    它实际上是客户端项目中的 App.CS 填充。 Http 端点在那里启动,默认情况下,代码生成将 BaseAddressAuthorizationMessageHandler 添加到 httpclient。

    builder.Services.AddHttpClient("private", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
           .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
    

    我如何解决它是使用命名客户端,一个用于 Private,一个用于 Public,就像这样

    builder.Services.AddHttpClient("private", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
        .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
    
    builder.Services.AddHttpClient("public", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));
    

    并在页面中注入 IHttpClientFactory

    @inject IHttpClientFactory ClientFactory
    

    并从工厂创建一个命名客户端。

    var client = ClientFactory.CreateClient("public");
    

    这行得通。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-14
      相关资源
      最近更新 更多