仅使用 Windows 身份验证使用同源 Web API 时,Blazor 服务器身份验证失败 - 401 未经授权

时间:2021-02-17 16:29:02

标签: asp.net-core asp.net-core-webapi blazor windows-authentication unauthorized

我正在从 IIS 上发布的 Blazor 服务器应用程序调用 Web API,作为主站点下的 IIS 应用程序,仅在两者上都使用 Windows 身份验证。 这意味着应用了同源规则。

虽然我随请求发送网络凭据,但同源策略会阻止凭据到达 API 并始终获得一个

<块引用>

"错误:System.Net.Http.HttpRequestException:响应状态代码 不表示成功:401(未经授权)。”

没有任何有意义的额外信息。

我发现的唯一解决方法是在主站点上启用匿名身份验证,这对于暂存环境是可以的,但不能在生产环境中完成。

在 API 上,我需要知道请求来自哪里,为此我需要知道哪个用户发出了请求。

如何绕过同源规则并强制凭证通过 API 端点?

这是我所做的:

在 Startup.cs 上创建了一个用于依赖注入的 HttpClient 实例。

public void ConfigureServices(IServiceCollection services)
{
    [...]
    if (services.All(x => x.ServiceType != typeof(HttpClient)))
    {
        services.AddScoped(
            s =>
            {
                HttpClientHandler handler = new HttpClientHandler
                {
                    UseDefaultCredentials = false,
                    Credentials = Config.CredentialsCache,
                    PreAuthenticate = true,
                    AllowAutoRedirect = true,
                };
                HttpClient httpClient = new HttpClient(handler, false)
                {
                    BaseAddress = new Uri(Config.BaseUrl),
                };
                httpClient.DefaultRequestHeaders.Add("User-Agent", "MEC2SIGRE Dashboard");
                httpClient.DefaultRequestHeaders.Referrer = new Uri("http://mec2sigreqa.telecom.pt/Dashboard");
                httpClient.DefaultRequestHeaders.ConnectionClose = false;
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                return httpClient;
            });
    }

    services.AddScoped<MECDashBoardDataService>();
    [...]
}

(基于 Antti K. Koskela's Personal Professional Blog 提案。)

还有班级:

public class MECDashBoardDataService
{
    private readonly HttpClient httpClient;

    public MECDashBoardDataService(HttpClient _httpClient)
    {
        httpClient = _httpClient;
    }

    public async Task<TaskersRow> MECTaskersDataAsync()
    {
        //******** The error is raised here **********//
        return await httpClient.GetFromJsonAsync<TaskersRow>(string.Concat(Config.BaseUrl, "/api/mec_api/gettaskersdata"));
    }
}

我想这是一种相对简单的方法。

在 API 上:

[ApiController]
[Route("api/[controller]")]
public class MEC_APIController : ControllerBase
{
    [HttpGet]
    [ActionName("gettaskersdata")]
    [Route("gettaskersdata")]
    public async ValueTask<ActionResult<MECTaskersRow>> GetTaskersData()
    {
        await taskingScoped.InicializeTasking();
        MECTaskersRow MecTR = PushingDashboard.TaskersData;
        MecTR.Message = httpContextAccessor.HttpContext.User.Identity.Name; //Only for testing and prove that the credential doesn't reach this point
        return MecTR;
    }

    [HttpGet]
    public string Get()
    {
        return "Connecting OK.";
    }
}

在 IIS 上: Image of IIS Manager

我试过了:

BrowserHttpMessageHandler.DefaultCredentials = FetchCredentialsOption.Include;

但找不到如何使用它。我认为它不适用于 Blazor 服务器。

也试过了:

System.Threading.ExecutionContext.SuppressFlow()

但它搞砸了 Blazor!

也尝试过 CORS,但这里也没有运气。

在此先感谢我能得到的任何帮助! :-)

0 个答案:

没有答案