繁体   English   中英

在 ASP.NET 核心托管的 Blazor 应用程序中对服务器进行匿名调用

[英]Make anonymous call to Server in ASP.NET Core hosted Blazor App

我使用授权和 ASP.NET 核心托管选项从 VS 中包含的模板创建了 Blazor Webassembly 应用程序,如下所示:

创建 Blazor 对话框

我希望能够在未经身份验证的情况下向服务器发出 http 请求。 我通过注释掉[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();
    }
}

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
        }
    }
}

我得到的例外是在上面的代码中。 我怀疑问题出在App.razor页面中,但无法弄清楚。

有什么帮助吗?

有人发布然后在这里删除了一个答案,该答案说问题出在客户端项目的Program.cs文件中的以下行中:

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

我肯定缺少一些东西,否则不禁会认为这是一个重大疏忽,即未经身份验证就无法访问 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

资料来源: https://chrissinty.com/avoiding-accesstokennotavailableexception-when-using-blazor-webassembly-hosted-template-with-individual-user-accounts/

原因:模板中的默认配置使用 HTTP 客户端和名为 BaseAddressAuthorizationMessageHandler 的自定义消息处理程序。 此处理程序尝试将访问令牌附加到任何传出请求,如果找不到,则会引发异常。

解决方案:

首先创建一个class

public class PublicClient
{
    public HttpClient Client { get; }

    public PublicClient(HttpClient httpClient)
    {
        Client = httpClient;
    }
}

在启动时使用依赖注入注册 class

builder.Services.AddHttpClient<PublicClient>(client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));

在 razor 页面中使用它

@inject PublicClient PublicClient

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM