我正在尝试设置一个能够与Linux机器上的客户端通信的WCF服务。该服务应该能够支持会话,以便我可以跟踪客户端,因为我们维护每个客户的状态。
由于客户端将从托管服务的网络进入,我使用自定义UserNamePasswordValidator和ServiceAuthorization管理器来验证客户端。
如果我使用Security.Message.ClientCredentialType = MessageCredentialType.Windows,我可以从Windows机器连接到我的服务,并建立WCF会话。一切都很好,直到这里。
然而,正如我在开始时所说的那样,我需要让它与从Linux连接的客户端一起工作,我尝试使用SecurityMode.TransportWithMessageCredential和SecurityMode.Message。 WCF要求我使用证书加密通信,我做了。但是我无法让会话发挥作用。对于来自客户端的每个调用,ServiceSecurityContext.Current.AuthorizationContext.Id都会更改。
请不要指出在以下代码中应该更改的内容,以使其在不使用MessageCredentialType.Windows的情况下与WCF会话一起使用?
private void SetupHTTPService()
{
string httpUrl =
String.Format("{0}://{1}:{2}/MyService", "http", m_httpEndpoint, m_httpPort);
string wsdlUrl =
String.Format("{0}://{1}:{2}/MyService.API", "http", m_httpEndpoint, m_httpPort);
Console.WriteLine("Listening on " + httpUrl);
// Create the service host
m_httpServiceHost = new ServiceHost(typeof(Server), new Uri(httpUrl));
// Create the binding
WSHttpBinding wsHttpBinding = new WSHttpBinding();
wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
// Attach the custom u/p validator
// and the service authorization manager.
m_httpServiceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode =
System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
m_httpServiceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator =
new CustomUserNameValidator();
m_httpServiceHost.Authorization.ServiceAuthorizationManager = new CustomServiceAuthorizationManager();
wsHttpBinding.Security.Mode = SecurityMode.Message;
wsHttpBinding.ReliableSession.Enabled = true;
SetCertificate(m_httpServiceHost);
m_httpServiceHost.AddServiceEndpoint(typeof(IServer), wsHttpBinding, httpUrl);
m_httpServiceHost.Open();
}
private void SetCertificate(ServiceHost serviceHost)
{
WCFPluginSection configuration = System.Configuration.ConfigurationManager.GetSection("WCFPlugin") as WCFPluginSection;
if (configuration != null)
{
bool encryptCommunication = configuration.EncryptUsingCertificate;
if (encryptCommunication)
{
StoreLocation storeLocation = configuration.CertificateStoreLocation;
StoreName storeName = configuration.CertificateStoreName;
string certificateName = configuration.CertificateName;
if( storeLocation == 0 || storeName == 0 || String.IsNullOrEmpty(certificateName))
throw new Exception("Certificate settings are not valid!");
serviceHost.Credentials.ServiceCertificate.SetCertificate(
storeLocation,
storeName,
X509FindType.FindBySubjectName,
certificateName);
}
}
}
底线是,如果我使用SecurityMode.TransportWithMessageCredential或SecurityMode.Message,则WCF会话无法正常工作。