我正在运行使用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/