如何在Azure App Service中使用带有WCF的X509Certificate2

时间:2016-09-06 19:07:45

标签: c# wcf azure x509certificate azure-web-app-service

我目前正在开发一个在Azure App Service中运行的应用程序,该应用程序使用带有TransportWithMessageCredential的WCF调用另一个服务,以便为消息凭据进行安全性和基于证书的身份验证。我能够从Azure Key Vault检索证书,并将该证书用于我的WCF ChannelFactory,以便客户端在我的本地开发盒上使用该服务。但是,只要我在Azure App Service vm上运行该应用程序,我的所有调用都会出现以下异常:

System.Security.Cryptography.CryptographicException: m_safeCertContext is an invalid handle.
   at System.Runtime.AsyncResult.End (System.ServiceModel.Internals, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.ServiceModel.Channels.ServiceChannel+SendAsyncResult.End (System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.ServiceModel.Channels.ServiceChannel.EndCall (System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.ServiceModel.Channels.ServiceChannelProxy+TaskCreator+<>c__DisplayClass7_0`1.<CreateGenericTask>b__0 (System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at MyAzureAppServiceApp.Util.ServiceModelClient.ChannelFactoryExtensions+<UsingResultAsync>d__3`2.MoveNext (MyAzureAppServiceApp.Util.ServiceModelClient, Version=1.2.906.10, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at MyAzureAppServiceApp.Data.WidgetRepository+<GetWidgetsByProjectAsync>d__5.MoveNext (MyAzureAppServiceApp.Data, Version=1.2.906.10, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at MyAzureAppServiceApp.Service.Controllers.WidgetController+<GetWidgetsByProjectNumberAsync>d__6.MoveNext (MyAzureAppServiceApp.Service, Version=1.2.906.10, Culture=neutral, PublicKeyToken=null)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Threading.Tasks.TaskHelpersExtensions+<CastToObject>d__3`1.MoveNext (System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Web.Http.Controllers.ApiControllerActionInvoker+<InvokeActionAsyncCore>d__0.MoveNext (System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Web.Http.Controllers.ActionFilterResult+<ExecuteAsync>d__2.MoveNext (System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Web.Http.Filters.AuthorizationFilterAttribute+<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext (System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Web.Http.Filters.AuthorizationFilterAttribute+<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext (System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Web.Http.Controllers.ExceptionFilterResult+<ExecuteAsync>d__0.MoveNext (System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)

从目前为止我能够确定的情况来看,X509Certificate2ChannelFactory的通话中使用Dispose()的时候看起来似乎是ChannelFactory。已经MySampleApp/app/src/main/java/com/amazonaws d了。我也已经尝试将证书的新副本注入我的input,我仍然得到同样的错误。有没有人遇到过这样的尝试从Azure App Service应用程序使用WCF的事情?

2 个答案:

答案 0 :(得分:1)

经过几天的挣扎,我的作者被this blog post引导。将此与一些改进的异常处理和测试相结合,我发现你需要指定加载标志MachineKeySet |可以导出为X509Certificate2的构造函数,否则证书将无法在Azure App Service环境中正确加载。这是因为Azure App Service VM不运行本地用户配置文件,因此没有可用的用户密钥库。这与X509Certificate2的构造函数及其存储私钥的默认值有关。

答案 1 :(得分:0)

我面临着同样的问题。对我来说,问题是我的代码类似于:

using(var certificate = new X509Certificate2(privateKeyBytes, ...)
{
    ...
    return certificate;
}

似乎证书在退还之前已被销毁。删除using声明后,它开始起作用。

不确定是否与您的情况有关,但我认为值得将其记录在某处:)