Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从服务器端Blazor应用程序调用API时,用户声明始终为空_C#_Asp.net Core_Blazor Server Side - Fatal编程技术网

C# 从服务器端Blazor应用程序调用API时,用户声明始终为空

C# 从服务器端Blazor应用程序调用API时,用户声明始终为空,c#,asp.net-core,blazor-server-side,C#,Asp.net Core,Blazor Server Side,我有一个.NET核心项目,它托管一个WebAPI和一个服务器端Blazor应用程序。应用程序通过IdentityDbContext使用默认身份验证和授权,并为Blazor使用默认的AuthenticationStateProvider。由于我希望这个应用在将来某个时候可能会移动到客户端Blazor,我一直在API中保留服务器端逻辑,并通过HttpClient调用它,我在启动时使用services.AddScoped()手动注入了它 我遇到的问题是,在调用API时,用户声明(即HttpContex

我有一个.NET核心项目,它托管一个WebAPI和一个服务器端Blazor应用程序。应用程序通过
IdentityDbContext
使用默认身份验证和授权,并为Blazor使用默认的
AuthenticationStateProvider
。由于我希望这个应用在将来某个时候可能会移动到客户端Blazor,我一直在API中保留服务器端逻辑,并通过
HttpClient
调用它,我在启动时使用
services.AddScoped()手动注入了它

我遇到的问题是,在调用API时,用户声明(即
HttpContext.User
)在API控制器中为空。当我说空时,
HttpContext.User
对象不是空的,但是所有的值都是默认值。预期的行为是使用登录用户的身份信息填充声明

奇怪的是,浏览器中出现了identity cookie
.AspNetCore.identity.Application
,并且
AuthenticationStateProvider
服务中的值与登录用户的预期值一致。对我来说,这表明在身份验证和标识方面,所有配置都是正确的,并且问题与
HttpClient
或Api控制器有关

我试过:

  • 在cookie配置中将
    HttpOnly
    设置为false,并通过JSInterop手动检索cookie以附加
    HttpClient
    头。这失败了,因为API调用在JSInterop抓取完cookie之前就开始了
  • 通过
    services.AddHttpClient()将
    HttpClient
    手动注入my
    ApiService
  • 从工作项目复制启动配置并覆盖我的项目
  • 以各种不同的方式更改已配置服务的顺序
  • 几种不同的cookie配置
  • 创建和使用自定义
    AuthenticationStateProvider
  • 遵循Microsoft官方文档中的几个不同指南
  • 回顾无数关于类似问题的文章和问题,尝试他们的建议
我还尝试通过以下方式将身份验证cookie手动添加到
HttpClient

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<HttpClient>(s =>
{
    var httpContextAccessor = s.GetRequiredService<IHttpContextAccessor>();
    string authToken = httpContextAccessor.HttpContext.Request.Cookies[".AspNetCore.Identity.Application"];

    var client = new HttpClient(new HttpClientHandler
    {
        UseCookies = false
    });

    if (authToken != null)
    {
        client.DefaultRequestHeaders.Add("Cookie", $".AspNetCore.Identity.Application={authToken}");
    }

    var request = httpContextAccessor.HttpContext.Request;
    client.BaseAddress = new Uri($"{request.Scheme}://{request.Host}/");
    return client;
});
services.AddSingleton();
services.AddScoped(s=>
{
var httpContextAccessor=s.GetRequiredService();
字符串authToken=httpContextAccessor.HttpContext.Request.Cookies[“.AspNetCore.Identity.Application”];
var client=新的HttpClient(新的HttpClientHandler
{
UseCookies=false
});
if(authToken!=null)
{
client.DefaultRequestHeaders.Add(“Cookie”,$”.AspNetCore.Identity.Application={authToken});
}
var request=httpContextAccessor.HttpContext.request;
client.BaseAddress=新Uri($“{request.Scheme}://{request.Host}/”;
返回客户;
});

此解决方案失败,因为调用委托时
httpContextAccessor
返回null。我知道没有HttpContext与信号器连接,但是,当应用程序首次加载、页面刷新或进行API调用时,我仍然希望有HttpContext。我还尝试了一个空检查版本,只有当
HttpContext
为非空时,它才会继续,但也失败了,因为
HttpContext
从来都不是非空的。

我能够通过将身份验证令牌直接传递到Blazor应用程序,然后以这种方式将其添加到
HttpClient

虽然我的应用程序托管在MVC视图中,但我知道托管Blazor应用程序最常见的方式是通过Razor页面。对于其他遇到此问题的用户,Razor页面修改如下

\u Host.cshtml

@{
    var token = HttpContext.Request.Cookies[".AspNetCore.Identity.Application"];
}

<app>
    <component type="typeof(App)" param-Token="token" render-mode="ServerPrerendered" />
</app>
@model string

...

<app>
    <component type="typeof(App)" param-Token="@Model" render-mode="ServerPrerendered" />
</app>
Index.cshtml

@{
    var token = HttpContext.Request.Cookies[".AspNetCore.Identity.Application"];
}

<app>
    <component type="typeof(App)" param-Token="token" render-mode="ServerPrerendered" />
</app>
@model string

...

<app>
    <component type="typeof(App)" param-Token="@Model" render-mode="ServerPrerendered" />
</app>