Blazor 身份验证 - Http 调用确实适用于匿名
Blazor Authentication - Http calls does work for anonymous
我一直在玩 .net 5.0 的 blazor。我遇到了一个简单但烦人的问题:我正在尝试从 API 加载数据,但每次调用服务器 blazor 都希望用户登录。
我明白了,如果我们从 API 控制器中取出 [Authorize] 标签并且在剃须刀页面中没有 @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>
我认为这是因为您 CascadingAuthenticationState
封装了 Found
context 和 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>
我想到了解决方案...应该先看看它。
实际上是App.CS填写Client Project。 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");
这有效。
我一直在玩 .net 5.0 的 blazor。我遇到了一个简单但烦人的问题:我正在尝试从 API 加载数据,但每次调用服务器 blazor 都希望用户登录。
我明白了,如果我们从 API 控制器中取出 [Authorize] 标签并且在剃须刀页面中没有 @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>
我认为这是因为您 CascadingAuthenticationState
封装了 Found
context 和 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>
我想到了解决方案...应该先看看它。
实际上是App.CS填写Client Project。 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");
这有效。