我正在运行使用Nuget安装了IdentityServer4的dotnet core 2.2应用程序。当我构建一个docker容器并运行时,一切正常。当我将此容器部署到我的Google Kubernetes Engine群集时,它在启动时失败,并显示以下内容:

{
 insertId:  "18ykz2ofg4ipm0"
 labels: {
  compute.googleapis.com/resource_name:  "fluentd-gcp-v3.1.0-nndnb"
  container.googleapis.com/namespace_name:  "my_namespace"
  container.googleapis.com/pod_name:  "identity-deployment-5b8bd8745b-qn2v8"
  container.googleapis.com/stream:  "stdout"
 }
 logName:  "projects/my_project/logs/app"
 receiveTimestamp:  "2018-12-07T21:09:25.708527406Z"
 resource: {
  labels: {
   cluster_name:  "my_cluster"
   container_name:  "app"
   instance_id:  "4238697312444637243"
   namespace_id:  "my_namespace"
   pod_id:  "identity-deployment-5b8bd8745b-qn2v8"
   project_id:  "my_project"
   zone:  "europe-west2-b"
  }
  type:  "container"
 }
 severity:  "INFO"
 textPayload:  "System.NullReferenceException: Object reference not set
to an instance of an object.
   at
IdentityServer4.Services.DefaultUserSession.RemoveSessionIdCookieAsync()
   at
IdentityServer4.Services.DefaultUserSession.EnsureSessionIdCookieAsync()
   at
IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
"
 timestamp:  "2018-12-07T21:09:17Z"
}

正如我提到的那样,这在本地非常完美,并且在docker容器中运行时,只有在Kubernetes中才能看到这些错误。

我不确定我在这里用kubernetes错过了什么,但是任何帮助都将不胜感激。

最佳答案

最近几天这让我很烦。我怀疑这与最近在App Builder配置中弃用前一种机制有关:

   app.UseAuthentication().UseCookieAuthentication();  <-- no longer valid and apparently will not even compile now.

在ConfigureServices部分中已将其替换为以下内容:
  services.AddAuthentication("YourCookieName")
    .AddCookie("YourCookieName", options =>
    {
      options.ExpireTimeSpan = TimeSpan.FromDays(30.0);
    });

虽然我不确定identityserver4的确切突破是什么,但是在克隆identityserver4组件并进行调试之后,我能够隔离DefaultUserSession的构造函数,并使用一个以null到达的IHttpContextAccessor:

有问题的构造函数:
    public DefaultUserSession(
        IHttpContextAccessor httpContextAccessor,
        IAuthenticationSchemeProvider schemes,
        IAuthenticationHandlerProvider handlers,
        IdentityServerOptions options,
        ISystemClock clock,
        ILogger<IUserSession> logger)
    { ...

以下解决方案使您克服了这个错误,尽管希望identityserver4在不久的将来的发行版中能够解决这个问题。

您需要在ConfigureServices中添加IHttpContextAccessor服务:
public override void ConfigureServices(IServiceCollection services)
{
  ... other code omitted ...
  services.AddScoped<IHttpContextAccessor>(provider => new
       LocalHttpContextAccessor(provider));
  ... other code omitted ...
}

LocalHttpContextAccessor只是配置类中的私有(private)类,如下所示:
private class LocalHttpContextAccessor : IHttpContextAccessor
{
  public IServiceProvider serviceProvider { get; private set; }
  public HttpContext httpContext { get; set; }

  public LocalHttpContextAccessor(IServiceProvider serviceProvider)
  {
    this.serviceProvider = serviceProvider;
    this.httpContext = null;
  }

  public HttpContext HttpContext
  {
    get
    {
      return this.httpContext;
    }
    set
    {
      this.httpContext = null;
    }
  }
}

问题在于,在配置服务时,没有当前上下文可供设置,因此我在应用程序构建器配置阶段的using块中进行了设置:
public override void Configure(IApplicationBuilder app,
  IHostingEnvironment env)
{
  app.Use(async (context, next) =>
  {
    IHttpContextAccessor httpContextAccessor;

    httpContextAccessor = context.RequestServices.GetRequiredService<IHttpContextAccessor>();
    if (httpContextAccessor is LocalHttpContextAccessor)
    {
      ((LocalHttpContextAccessor)httpContextAccessor).httpContext = context;
    }
    await next();
  });
  ... other code omitted ...
  app.UseIdentityServer();

这将在运行可修复该错误的身份服务器代码之前设置http上下文。应该为每个请求分别创建范围服务。我只是最近才从.net框架完全陷入.net核心,因此,如果该代码中存在范围或DI问题,可能会导致泄漏或不良的生命周期,我将不胜感激。也就是说,至少该代码可以防止身份服务器4与核心2.2+崩溃。

关于c# - 使用IdentityServer4加载项目时,DefaultUserSession中的NullReferenceException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53676909/

10-10 04:29