Asp.net core Blazor身份验证-Http调用适用于匿名

Asp.net core Blazor身份验证-Http调用适用于匿名,asp.net-core,blazor,forms-authentication,blazor-webassembly,blazor-client-side,Asp.net Core,Blazor,Forms Authentication,Blazor Webassembly,Blazor Client Side,我一直在用.NET5.0玩blazor。我遇到了一个简单但恼人的问题:我试图从API加载数据,但对服务器blazor的每次调用都希望用户登录 我理解如果我们从API控制器中取出[Authorize]标记,并且在razor页面中没有@attribute[Authorize],那就是了。但是我很难理解为什么我的API调用仍然需要在protectedoverride async Task OnInitializedAsync()中使用AccessToken,错误消息并没有详细说明原因 Microsof

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

我理解如果我们从API控制器中取出[Authorize]标记,并且在razor页面中没有
@attribute[Authorize]
,那就是了。但是我很难理解为什么我的API调用仍然需要在
protectedoverride 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>

@如果(!context.User.Identity.IsAuthenticated)
{
}
其他的
{
您无权访问此资源

} 正在进行身份验证。。。 对不起,这个地址什么也没有


我认为这是因为您有
CascadingAuthenticationState
封装了
Found
上下文和
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>

@如果(!context.User.Identity.IsAuthenticated)
{
}
其他的
{
您无权访问此资源

} 正在进行身份验证。。。 对不起,这个地址什么也没有


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

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

builder.Services.AddHttpClient("private", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
       .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
并从工厂创建一个命名客户端

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

这很有效。

请将您的应用程序上载到github。。。
@inject IHttpClientFactory ClientFactory
var client = ClientFactory.CreateClient("public");