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 セッションが機能しないということです。