为什么 Azure App Service 找不到我的 GoDaddy 证书?
Why can't Azure App Service find my GoDaddy certificate?
我有一个 Azure 应用服务 运行 一个 .NET Core 3.1 应用程序,使用 IdentityServer4 进行身份验证。
我的 appsettings.json
文件如下所示:
...
"IdentityServer": {
"Clients": {
"MyApp": {
"Profile": "IdentityServerSPA"
}
},
"Key": {
"Type": "Store",
"StoreName": "My",
"StoreLocation": "CurrentUser",
"Name": "CN=mydomain.com"
}
},
...
我通过 GoDaddy 使用以下(假)值创建了一个证书:
- 指纹:
my-thumbprint
- 主题名称:
app.mydomain.com,www.app.mydomain.com
此证书已作为私钥证书上传到我的应用服务,并且还存储在 Azure Key Vault 中(在自定义域绑定配置期间)。
在我的应用服务配置设置中,我有以下设置:
WEBSITE_LOAD_CERTIFICATES
: my-thumbprint
IdentityServer__Key__Name
: CN=app.mydomain.com,www.app.mydomain.com
我的应用程序无法启动。启动 Azure 应用服务控制台和 运行 命令
dotnet myapp.dll
产生以下堆栈跟踪:
Unhandled exception. System.InvalidOperationException: Couldn't find a valid certificate with subject 'CN=app.addtheand.com,www.app.addtheand.com' on the 'CurrentUser\My'
at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.SigningKeysLoader.LoadFromStoreCert(String subject, String storeName, StoreLocation storeLocation, DateTimeOffset currentTime)
at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.LoadKey()
at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.Configure(ApiAuthorizationOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at System.Lazy`1.get_Value()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions.<>c.<AddClients>b__7_1(IServiceProvider sp)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.TestService(IServiceProvider serviceProvider, Type service, ILogger logger, String message, Boolean doThrow)
at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.Validate(IApplicationBuilder app)
at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.UseIdentityServer(IApplicationBuilder app, IdentityServerMiddlewareOptions options)
我错过了什么?
我的应用程序在 DEV 模式下按预期运行,它使用 appsettings.json
中的 IdentityServer 配置而无需修改,loading/using 不同的自签名证书。
更新
我检查了证书是否加载到应用程序服务机器,但没有找到。
找到这个的步骤:
- 从 Azure 门户中的应用服务,启动 kudo
- 在 kudo 中,select 调试控制台 -> Powershell
- 运行以下命令:
dir cert:\localmachine\my
更新 2
因为我试图通过 CurrentUser 加载证书,所以我改为 运行 在 powershell 终端中执行以下命令:dir cert:\CurrentUser\My
,发现主题与我在Azure 门户。
- 门户中的主题:
app.mydomain.com,www.app.mydomain.com
- 输出主题:
CN=app.mydomain.com, OU=Domain Co...
跟进 更新 2...
我在通过 UI 查看证书时在 Azure 门户中看到的 Subject 与我在 运行 时看到的不匹配dir cert:\CurrentUser\my
通过 kudo 的 Powershell 控制台的命令是我问题的根源。
为了修复,我根据 Portal UI:
从 subject 更改了 IdentityServer__Key__Name
的配置值
CN=app.mydomain.com,www.app.mydomain.com
根据上面的命令给主题:
CN=app.mydomain.com, OU=Domain Control Validated
我有一个 Azure 应用服务 运行 一个 .NET Core 3.1 应用程序,使用 IdentityServer4 进行身份验证。
我的 appsettings.json
文件如下所示:
...
"IdentityServer": {
"Clients": {
"MyApp": {
"Profile": "IdentityServerSPA"
}
},
"Key": {
"Type": "Store",
"StoreName": "My",
"StoreLocation": "CurrentUser",
"Name": "CN=mydomain.com"
}
},
...
我通过 GoDaddy 使用以下(假)值创建了一个证书:
- 指纹:
my-thumbprint
- 主题名称:
app.mydomain.com,www.app.mydomain.com
此证书已作为私钥证书上传到我的应用服务,并且还存储在 Azure Key Vault 中(在自定义域绑定配置期间)。
在我的应用服务配置设置中,我有以下设置:
WEBSITE_LOAD_CERTIFICATES
:my-thumbprint
IdentityServer__Key__Name
:CN=app.mydomain.com,www.app.mydomain.com
我的应用程序无法启动。启动 Azure 应用服务控制台和 运行 命令
dotnet myapp.dll
产生以下堆栈跟踪:
Unhandled exception. System.InvalidOperationException: Couldn't find a valid certificate with subject 'CN=app.addtheand.com,www.app.addtheand.com' on the 'CurrentUser\My'
at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.SigningKeysLoader.LoadFromStoreCert(String subject, String storeName, StoreLocation storeLocation, DateTimeOffset currentTime)
at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.LoadKey()
at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.Configure(ApiAuthorizationOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at System.Lazy`1.get_Value()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions.<>c.<AddClients>b__7_1(IServiceProvider sp)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.TestService(IServiceProvider serviceProvider, Type service, ILogger logger, String message, Boolean doThrow)
at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.Validate(IApplicationBuilder app)
at Microsoft.AspNetCore.Builder.IdentityServerApplicationBuilderExtensions.UseIdentityServer(IApplicationBuilder app, IdentityServerMiddlewareOptions options)
我错过了什么?
我的应用程序在 DEV 模式下按预期运行,它使用 appsettings.json
中的 IdentityServer 配置而无需修改,loading/using 不同的自签名证书。
更新
我检查了证书是否加载到应用程序服务机器,但没有找到。
找到这个的步骤:
- 从 Azure 门户中的应用服务,启动 kudo
- 在 kudo 中,select 调试控制台 -> Powershell
- 运行以下命令:
dir cert:\localmachine\my
更新 2
因为我试图通过 CurrentUser 加载证书,所以我改为 运行 在 powershell 终端中执行以下命令:dir cert:\CurrentUser\My
,发现主题与我在Azure 门户。
- 门户中的主题:
app.mydomain.com,www.app.mydomain.com
- 输出主题:
CN=app.mydomain.com, OU=Domain Co...
跟进 更新 2...
我在通过 UI 查看证书时在 Azure 门户中看到的 Subject 与我在 运行 时看到的不匹配dir cert:\CurrentUser\my
通过 kudo 的 Powershell 控制台的命令是我问题的根源。
为了修复,我根据 Portal UI:
从 subject 更改了IdentityServer__Key__Name
的配置值
CN=app.mydomain.com,www.app.mydomain.com
根据上面的命令给主题:
CN=app.mydomain.com, OU=Domain Control Validated