identityserver4 - 使用 docker 启动 Identity Server 中的 X509Store 异常
问题描述
我正在尝试将我们的 IdentityServer4 项目转换为 docker。我添加了正确的 dockerfile,它可以构建。它是 .net core 3.1 但我得到一个启动错误
PlatformNotSupportedException:Unix LocalMachine X509Store 仅限于 Root 和 CertificateAuthority 存储。
我在另一篇文章IdentityServer4: How to load Signing Credential from Cert Store when in Docker中查看了这个确切的错误, 唯一的答案对我不起作用。这是我的 Dockerfile
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["src/Sentinel.Web/is4.Web.csproj", "src/is4.Web/"]
RUN dotnet restore "src/is4.Web/is4.Web.csproj"
COPY . .
WORKDIR "/src/src/is4.Web"
RUN dotnet build "is4.Web.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "is4.Web.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
COPY "IdentityServerCN.pfx" .
COPY "IdentityServerDataKeysCN.pfx" .
ENTRYPOINT ["dotnet", "Sentinel.Web.dll"]
我什至尝试将其更改为使用开发人员证书,但仍然没有运气
.AddDeveloperSigningCredential(); // debug only
启动类:
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("IdentityServer")));
services
.AddDbContext<DataKeysContext>(o =>
{
o.UseSqlServer(Configuration.GetConnectionString("IdentityServer"));
o.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
if (Configuration.GetValue<bool?>("EnableSensitiveDataLogging") ?? false)
{
o.EnableSensitiveDataLogging(); // debug only
}
})
.AddDataProtection()
.PersistKeysToDbContext<DataKeysContext>()
.ProtectKeysWithCertificate(GetCertficateFromKeystore(Configuration.GetValue<string>("Certificates:DataProtection")))
.SetDefaultKeyLifetime(TimeSpan.FromDays(7))
.SetApplicationName("Sentinel.Web");
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// If we're in dev allow showing PII for debugging identity server cert issues
IdentityModelEventSource.ShowPII = Configuration.GetValue<bool?>("ShowIdentityModelPII") ?? false;
// configures IIS out-of-proc settings (see https://github.com/aspnet/AspNetCore/issues/14882)
services.Configure<IISOptions>(iis =>
{
iis.AuthenticationDisplayName = "Windows";
iis.AutomaticAuthentication = false;
});
// configures IIS in-proc settings
services.Configure<IISServerOptions>(iis =>
{
iis.AuthenticationDisplayName = "Employee Account";
iis.AutomaticAuthentication = false;
});
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
})
.AddDefaultEndpoints()
//.AddSigningCredential(GetCertficateFromKeystore(Configuration.GetValue<string>("Certificates:IdentityServer")))
//.AddSigningCredential(new X509Certificate2("IdentityServerCN.pfx", "pass1234") )
//.AddInMemoryPersistedGrants()
.AddOperationalStore(options =>
{
options.DefaultSchema = "dbo";
options.ConfigureDbContext = x =>
x.UseSqlServer(Configuration.GetConnectionString("IdentityServer"));
})
//.AddTestUsers(TestUsers.Users)
.AddInMemoryIdentityResources(Configuration.GetSection("IdentityResources"))
.AddInMemoryApiResources(Configuration.GetSection("ApiResources"))
.AddInMemoryClients(Configuration.GetSection("Clients"))
.AddAspNetIdentity<ApplicationUser>()
.AddDeveloperSigningCredential(); // debug only
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "xxx.apps.googleusercontent.com";
options.ClientSecret = "xxxxxxxxxxxx";
});
// If we did a custom grant store (i.e. instead of using EF we could use dapper)
//services.AddTransient<IPersistedGrantStore, PersistedGrantStore>();
services.AddTransient<ActiveDirectoryService>();
}
public void Configure(IApplicationBuilder app)
{
if (Configuration.GetValue<bool?>("ShowDeveloperExceptionPage") ?? false)
{
app.UseDeveloperExceptionPage();
//app.UseDatabaseErrorPage();
}
app.UseStaticFiles();
// CORS handled by identity server settings
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
private X509Certificate2 GetCertficateFromFileSystem(string keyFilePath, string keyFilePassword)
{
// using file
return new X509Certificate2(keyFilePath, keyFilePassword, X509KeyStorageFlags.MachineKeySet);
}
private X509Certificate2 GetCertficateFromKeystore(string keyIssuer)
{
// using keystore
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindByIssuerName, keyIssuer, true);
if (certificates.Count == 0)
{
throw new InvalidOperationException("Could not locate certificate in keystore");
}
return certificates[0];
}
}
解决方案
推荐阅读
- c - 如何在二进制搜索中使用结构?
- swift - 将 UnsafeMutablePointer 的实部提取为浮点数并将其存储在数组中
- vue.js - RadDataForm 更新示例
- javascript - Uncaught TypeError: $(...).sidebar is not a function 但 semantic.js 包含在 head
- xml - 如何使 Perl 的 XML::Libxml 序列化程序使用 utf-8 编码?
- javascript - 如何将我网站上的表单字段中的输入数据发送到不和谐的 webhook,该 webhook 向不和谐的用户发送消息?
- c# - Sql Server 读取具有不同数量字段的文本文件
- swift - “SecondPageController”类型的值没有成员“miniView”
- shell - 以 * 作为参数值的容器内的 shell 脚本
- linux - 查找包含 20 个元音的单词 grep