[英]Make anonymous call to Server in ASP.NET Core hosted Blazor App
I created a Blazor Webassembly app from the included template in VS with Authorization and ASP.NET Core hosted options as shown here:我使用授权和 ASP.NET 核心托管选项从 VS 中包含的模板创建了 Blazor Webassembly 应用程序,如下所示:
I want to be able to make http requests to the server without being authenticated.我希望能够在未经身份验证的情况下向服务器发出 http 请求。 I changed the code in the WeatherForecastController
by commenting out the [Authorize]
attribute (and even added an [AllowAnonymous]
attribute):我通过注释掉[Authorize]
属性(甚至添加了[AllowAnonymous]
属性)更改了WeatherForecastController
中的代码:
//[Authorize] CHANGED
[AllowAnonymous] //CHANGED
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
In the FetchData.razor
page, along with other changes noted in the code, I commented out @attribute [Authorize]
:在FetchData.razor
页面中,连同代码中提到的其他更改,我注释掉了@attribute [Authorize]
:
@page "/fetchdata"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using StackOverflowAuthProblem.Shared
@*@attribute [Authorize]*@ @*CHANGED*@
@inject HttpClient Http
@*CHANGED Html removed for brevity*@
<div>Exception message: @exceptionMessage</div>
@code {
private WeatherForecast[] forecasts;
string exceptionMessage; //CHANGED
protected override async Task OnInitializedAsync()
{
try
{
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
}
catch (AccessTokenNotAvailableException exception)
{
exceptionMessage = exception.Message; //CHANGED returns an empty string
exceptionMessage = exception.ToString(); //CHANGED returns
//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)
//at System.Net.Http.Json.HttpClientJsonExtensions.<GetFromJsonAsyncCore>d__9`1[[StackOverflowAuthProblem.Shared.WeatherForecast[],
//StackOverflowAuthProblem.Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
//at StackOverflowAuthProblem.Client.Pages.FetchData.OnInitializedAsync()
//in E:\StackOverflow\StackOverflowAuthProblem\StackOverflowAuthProblem\Client\Pages\FetchData.razor:line 53
//exception.Redirect(); CHANGE
}
}
}
The exception I get is in the code above.我得到的例外是在上面的代码中。 I suspect the problem is in the App.razor
page, but can't figure it out.我怀疑问题出在App.razor
页面中,但无法弄清楚。
Any help?有什么帮助吗?
Someone posted then deleted an answer here which said the problem was in following line in the Program.cs
file of the client project:有人发布然后在这里删除了一个答案,该答案说问题出在客户端项目的Program.cs
文件中的以下行中:
builder.Services.AddHttpClient("RclConsumer.ServerAPI", client => client.BaseAddress = new
Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
Surely there's something I'm missing, otherwise can't help but think this is a major oversight that one can't hit an API endpoint without being authenticated.我肯定缺少一些东西,否则不禁会认为这是一个重大疏忽,即未经身份验证就无法访问 API 端点。
public static class HttpClientService
{
public static HttpClient AnonymousHttpClient { get; set; }
static HttpClientService()
{
AnonymousHttpClient = new HttpClient();
#if DEBUG
AnonymousHttpClient.BaseAddress = new Uri("https://localhost:44395/");
#else
throw new Exception("Need the Base address here");
#endif
}
}
My reasoning for putting it in it's own class library is that I plan on adding Razor Class Libraries and I want a single instance of the HttpClient
to use across the solution because of the problem with sockets My reasoning for putting it in it's own class library is that I plan on adding Razor Class Libraries and I want a single instance of the HttpClient
to use across the solution because of the problem with sockets
Source: https://chrissainty.com/avoiding-accesstokennotavailableexception-when-using-blazor-webassembly-hosted-template-with-individual-user-accounts/资料来源: https://chrissinty.com/avoiding-accesstokennotavailableexception-when-using-blazor-webassembly-hosted-template-with-individual-user-accounts/
Reason: The default configuration in the template uses an HTTP client with a custom message handler called BaseAddressAuthorizationMessageHandler.原因:模板中的默认配置使用 HTTP 客户端和名为 BaseAddressAuthorizationMessageHandler 的自定义消息处理程序。 This handler attempts to attach an access token to any outgoing requests and if it can't find one, it throws an exception.此处理程序尝试将访问令牌附加到任何传出请求,如果找不到,则会引发异常。
Solution:解决方案:
First create a class首先创建一个class
public class PublicClient
{
public HttpClient Client { get; }
public PublicClient(HttpClient httpClient)
{
Client = httpClient;
}
}
Register the class with Dependency Injection in the start up在启动时使用依赖注入注册 class
builder.Services.AddHttpClient<PublicClient>(client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));
Use it in razor pages在 razor 页面中使用它
@inject PublicClient PublicClient
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.