我正在编写Azure WCF服务总线服务,该服务将以编程方式配置为使用证书来保护邮件安全:
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Tcp;
// create the service URI based on the service namespace
Uri address = ServiceBusEnvironment.CreateServiceUri("sb", ConfigurationManager.AppSettings["serviceNamespace"], "TestService");
// create the credentials object for the endpoint
TransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(ConfigurationManager.AppSettings["issuerName"], ConfigurationManager.AppSettings["issuerSecret"]);
//Create and bind the serviceEndpoint
ContractDescription contractDescription = ContractDescription.GetContract(typeof(ITestContract), typeof(TestServiceImpl));
ServiceEndpoint serviceEndPoint = new ServiceEndpoint(contractDescription);
serviceEndPoint.Address = new EndpointAddress(address);
var NetTcpRelayBinding = new NetTcpRelayBinding(EndToEndSecurityMode.TransportWithMessageCredential, RelayClientAuthenticationType.RelayAccessToken);
NetTcpRelayBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; //The serivice will check the TrustedPeople store for the client
serviceEndPoint.Binding = NetTcpRelayBinding;
serviceEndPoint.Behaviors.Add(sharedSecretServiceBusCredential);
Host = new ServiceHost(typeof(TestServiceImpl), address);
//Add a service certificate
Host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerTrust;
Host.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,StoreName.My,X509FindType.FindByThumbprint,"E86870F0118CE39D771A49B9337C28444F3C7348");
// create the service host reading the configuration
Host.Description.Endpoints.Add(serviceEndPoint);
我可以启动并运行此服务,但是,任何客户端)只有ServiceBus SharedSecret,clientCredentials未设置为使用任何证书)能够毫无错误地调用我的服务。 上面的代码是否足以表明应该使用证书(并且只有证书基础授权)来实现消息安全性? 有关以编程方式配置WCF消息安全性的任何好文章吗?
答案 0 :(得分:0)
事实证明,睡眠不足是罪魁祸首;我正在运行旧版本的服务。没有任何证书的客户端会出错(System.ServiceModel.ProtocolException未读取消息=在读取流的位置1处的消息帧格式时出错(状态:开始)。
正确编码的客户端是:
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Tcp;
string serviceNamespace = "valid-namespace";
string issuerName = "owner";
string issuerSecret = "validSecret";
// create the service URI based on the service namespace
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace, "valid-namespace");
// create the credentials object for the endpoint
TransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.CredentialType = TransportClientCredentialType.SharedSecret;
sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerName = issuerName;
sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerSecret = issuerSecret;
ChannelFactory<ITestChannel> channelFactory = new ChannelFactory<ITestChannel>();
channelFactory.Endpoint.Address = new EndpointAddress(serviceUri);
var NTRB = new NetTcpRelayBinding();
NTRB.Security.Mode = EndToEndSecurityMode.TransportWithMessageCredential;
NTRB.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
channelFactory.Endpoint.Binding = NTRB;
channelFactory.Endpoint.Contract.ContractType = typeof(ITestChannel);
// apply the Service Bus credentials
channelFactory.Endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
//Question : Why doesn't use of the following line effect Service-Validation ? I can successfully call the service from a machine where the server's certificate does NOT exist in the trusted-people store
//channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.PeerTrust;
channelFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "valid-thubmprint");
// create and open the client channel
ITestChannel channel = channelFactory.CreateChannel();
Console.WriteLine(channel.ServiceMethod());
Console.ReadKey();
channel.Close();
channelFactory.Close();
即使PeerTrust用于channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode且服务证书不在TrustedPeople存储中,仍然存在始终假定ServiceCertificate有效的问题。 有没有想过会发生这种情况的人?