Azure 应用服务上 WCF 服务 运行 的 SSL 设置问题
Problem with SSL settings for WCF service running on Azure app service
我目前正在开发一个 wcf web 服务 (.NET 4.7.2),它接受来自不同来源的 soap 消息。其中一个来源要求我们使用自定义授权机构 (CA) 创建一个由证书保护的端点。
为此,我创建了一个新的 .svc 文件,该文件使用以下绑定进行初始化并导入证书。此证书可在 Azure Web 应用程序中访问:
public static void Configure(ServiceConfiguration config)
{
// Enable "Add Service Reference" support
config.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpsGetEnabled = true, HttpGetEnabled = false }); //mex
//setup support for certficate security
var binding = new WSHttpBinding
{
Name = "CertificateBinding",
ReaderQuotas = { MaxArrayLength = int.MaxValue },
MaxReceivedMessageSize = int.MaxValue,
Security = new WSHttpSecurity
{
Mode = SecurityMode.Transport,
Transport = new HttpTransportSecurity
{
ClientCredentialType = HttpClientCredentialType.Certificate
},
},
};
config.EnableProtocol(binding);
config.Credentials.ServiceCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, "Thumbprint inserted here");
config.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });
}
为了为此端点启用证书身份验证,我将以下内容添加到 web.config;
<location path="IntegrationWebService_CertificateSecurity.svc">
<system.webServer>
<httpErrors errorMode="Detailed"></httpErrors>
<security>
<access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" />
</security>
</system.webServer>
</location>
我对此进行了测试,这一切都在本地运行良好,但是当部署到 Azure Web 应用程序时,它显示 500 错误。我似乎无法弄清楚这个 500 错误的原因。其他 .svc 文件继续正常工作。
我试过的;
添加 ELMAH;没有记录异常。
SslSettings 的多个配置,none 有效,但仅添加“SslRequireCert”会将错误更改为“服务 'SslRequireCert' 的 SSL 设置与 IIS 的设置不匹配'None'”。我不再坚持这一点,因为据我所知,SslNegotiateCert 部分是必需的。
已尝试添加一个 applicationHost.xdt 文件来转换 overrideModeDefault 以允许像这样覆盖:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<configSections>
<sectionGroup name="system.webServer" xdt:Locator="Match(name)">
<sectionGroup name="security" xdt:Locator="Match(name)">
<section name="access" overrideModeDefault="Allow" xdt:Locator="Match(name)" xdt:Transform="SetAttributes(overrideModeDefault)" />
</sectionGroup>
</sectionGroup>
</configSections>
</configuration>
难道是 Azure 不允许在 SslFlags 中自定义值?
显然,对于 Azure,您不能使用 System.ServiceModel 要求客户端证书。因此,首先您可以关闭需要客户端证书的部分。使用 CustomBinding 执行此操作如下所示:
var httpsBE = new HttpsTransportBindingElement();
httpsBE.RequireClientCertificate = false;
httpsBE.AuthenticationScheme = AuthenticationSchemes.Anonymous;
然后,Azure 所做的是将证书从原始请求移动到 X-ARR-ClientCert header。这可以在这样的网络服务中访问;
var certHeader = WebOperationContext.Current.IncomingRequest.Headers["X-ARR-ClientCert"];
并将其转换为 X509Certificate2:
var clientCertBytes = Convert.FromBase64String(certHeader);
var x509Certificate2 = new X509Certificate2(clientCertBytes);
然后你必须运行你自己的证书验证。
我目前正在开发一个 wcf web 服务 (.NET 4.7.2),它接受来自不同来源的 soap 消息。其中一个来源要求我们使用自定义授权机构 (CA) 创建一个由证书保护的端点。
为此,我创建了一个新的 .svc 文件,该文件使用以下绑定进行初始化并导入证书。此证书可在 Azure Web 应用程序中访问:
public static void Configure(ServiceConfiguration config)
{
// Enable "Add Service Reference" support
config.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpsGetEnabled = true, HttpGetEnabled = false }); //mex
//setup support for certficate security
var binding = new WSHttpBinding
{
Name = "CertificateBinding",
ReaderQuotas = { MaxArrayLength = int.MaxValue },
MaxReceivedMessageSize = int.MaxValue,
Security = new WSHttpSecurity
{
Mode = SecurityMode.Transport,
Transport = new HttpTransportSecurity
{
ClientCredentialType = HttpClientCredentialType.Certificate
},
},
};
config.EnableProtocol(binding);
config.Credentials.ServiceCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, "Thumbprint inserted here");
config.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });
}
为了为此端点启用证书身份验证,我将以下内容添加到 web.config;
<location path="IntegrationWebService_CertificateSecurity.svc">
<system.webServer>
<httpErrors errorMode="Detailed"></httpErrors>
<security>
<access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" />
</security>
</system.webServer>
</location>
我对此进行了测试,这一切都在本地运行良好,但是当部署到 Azure Web 应用程序时,它显示 500 错误。我似乎无法弄清楚这个 500 错误的原因。其他 .svc 文件继续正常工作。
我试过的;
添加 ELMAH;没有记录异常。
SslSettings 的多个配置,none 有效,但仅添加“SslRequireCert”会将错误更改为“服务 'SslRequireCert' 的 SSL 设置与 IIS 的设置不匹配'None'”。我不再坚持这一点,因为据我所知,SslNegotiateCert 部分是必需的。
已尝试添加一个 applicationHost.xdt 文件来转换 overrideModeDefault 以允许像这样覆盖:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <configSections> <sectionGroup name="system.webServer" xdt:Locator="Match(name)"> <sectionGroup name="security" xdt:Locator="Match(name)"> <section name="access" overrideModeDefault="Allow" xdt:Locator="Match(name)" xdt:Transform="SetAttributes(overrideModeDefault)" /> </sectionGroup> </sectionGroup> </configSections> </configuration>
难道是 Azure 不允许在 SslFlags 中自定义值?
显然,对于 Azure,您不能使用 System.ServiceModel 要求客户端证书。因此,首先您可以关闭需要客户端证书的部分。使用 CustomBinding 执行此操作如下所示:
var httpsBE = new HttpsTransportBindingElement();
httpsBE.RequireClientCertificate = false;
httpsBE.AuthenticationScheme = AuthenticationSchemes.Anonymous;
然后,Azure 所做的是将证书从原始请求移动到 X-ARR-ClientCert header。这可以在这样的网络服务中访问;
var certHeader = WebOperationContext.Current.IncomingRequest.Headers["X-ARR-ClientCert"];
并将其转换为 X509Certificate2:
var clientCertBytes = Convert.FromBase64String(certHeader);
var x509Certificate2 = new X509Certificate2(clientCertBytes);
然后你必须运行你自己的证书验证。