我正在从App.config迁移到以编程方式进行迁移,以调用具有客户端证书身份验证/身份的WCF服务。新代码是.NET Core,但是测试控制台应用程序的目标框架已设置为net472,以便它可以在Azure Kudu中运行。
我到处搜索,但无法摆脱此错误消息。
错误:
未处理的异常:System.ServiceModel.Security.MessageSecurityException:传出消息的身份检查失败。对于“ net.tcp:// myserver:1001 / MyServiceRelay / MyServiceRelay.svc”目标端点,期望的身份是“ identity(http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint)”。
服务器堆栈跟踪: 在System.ServiceModel.Security.IdentityVerifier.EnsureIdentity(EndpointAddress serviceReference,AuthorizationContextauthorizationContext,String errorString) 在System.ServiceModel.Security.MessageSecurityProtocol.EnsureOutgoingIdentity(SecurityToken令牌,SecurityTokenAuthenticator身份验证器)处
App.config:
<endpoint name="MyEndpoint"
address="[PLACEHOLDER]"
binding="netTcpBinding"
bindingConfiguration="NetTcpAzureBinding"
behaviorConfiguration="AzureCertificateBehavior"
contract="MyCalledService">
<identity>
<certificate encodedValue="[PLACEHOLDER]" />
</identity>
</endpoint>
<netTcpBinding>
<binding name="NetTcpAzureBinding" maxReceivedMessageSize="20485760">
<readerQuotas maxArrayLength="20485760" maxStringContentLength="20485760" />
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</netTcpBinding>
<behavior name="AzureCertificateBehavior">
<clientCredentials>
<clientCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindByThumbprint" findValue="[PLACEHOLDER]" />
<serviceCertificate>
<authentication certificateValidationMode="None" revocationMode="NoCheck" />
</serviceCertificate>
</clientCredentials>
</behavior>
等效于代码:
// My FindCertificate method performs a lookup by thumbprint, exactly the same code that below when using "SetCertificate".
X509Certificate2 certificate = Common.FindCertificate(settings.CertificateThumbprint);
var binding = new NetTcpBinding
{
// custom constant
MaxReceivedMessageSize = Common.MaxReceivedMessageSize
};
// custom constant
binding.ReaderQuotas.MaxArrayLength = Common.MaxArrayLength;
// custom constant
binding.ReaderQuotas.MaxStringContentLength = Common.MaxStringContentLength;
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
var endpoint = new EndpointAddress(new Uri(settings.MailService.EndpointAddress), EndpointIdentity.CreateX509CertificateIdentity(certificate));
_channelFactory = new ChannelFactory<IMailService>(binding, endpoint);
_channelFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, settings.CertificateThumbprint);
_channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
_channelFactory.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
怎么了?感谢您的想法。
答案 0 :(得分:0)
好吧,什么都没有“错”,但是错误消息并不令人满意。一旦得到它,我只需要更换:
EndpointIdentity.CreateX509CertificateIdentity(certificate)
作者:
EndpointIdentity.CreateDnsIdentity(settings.MailService.EndpointDns)
端点身份初始化中的。期望值在错误消息中...
帮助我的是建立一个通道工厂,该工厂通过将经典的.config文件读取到配置类来进行初始化:
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "MailService.config";
Configuration newConfiguration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
_channelFactory = new ConfigurationChannelFactory<IMailService>("MyEndpoint", newConfiguration, new EndpointAddress("net.tcp://myserver:1001/MyServiceRelay/MyServiceRelay.svc"));
(嗯,这没有成功调用端点,只是提供了一个线索)。
仍然存在一个问题:为什么经典配置在不抱怨端点DNS的情况下仍能正常工作?我再次检查。我回想起2010年有关此安全检查的内容(防止网络欺诈)。同样有用:https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/service-identity-and-authentication
欢迎发表评论。