问题描述
我正在从 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 上:
我试过了:
browserHttpMessageHandler.DefaultCredentials = FetchCredentialsOption.Include;
但找不到如何使用它。我认为它不适用于 Blazor 服务器。
也试过了:
System.Threading.ExecutionContext.SuppressFlow()
但它搞砸了 Blazor!
也尝试过 CORS,但这里也没有运气。
在此先感谢我能得到的任何帮助! :-)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)