1

我正在尝试设置一个 WCF 服务,该服务应该能够与 Linux 机器上的客户端进行通信。该服务应该能够支持会话,以便我可以跟踪客户端,因为我们正在维护每个客户端的状态。

由于客户端将来自托管服务的网络以外的网络,因此我使用自定义 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 会话将不起作用。

4

0 回答 0