我正在运行一个使用 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.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 block 中:
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/