0

非常に厄介なエラーが発生しました: 私のシナリオ - wsdualhttpbinding (コールバックのデュアル、新しいメッセージのオンライン更新) を使用して WCF に実装された単純なメッセージ/メール サーバー\クライアント。

すべてのセキュリティ構成はコードで記述されています (*.config はまったくありません)。最初の接続時に、クライアントは次の [System.Security.Cryptography.CryptographicException] = {"Bad Length.\r\n"} を NULL 内部例外とともにスローするため、より深く掘り下げることはできません。サーバー構成:

     WSDualHttpBinding binding = new   WSDualHttpBinding(WSDualHttpSecurityMode.Message);
    binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

        Uri baseServiceAddress = new Uri(@"http://"+Environment.MachineName+":7921/Mail/");                 
        host = new ServiceHost(theMightyMailServer,baseServiceAddress);             

        host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
        host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
        host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = validator;
        host.Credentials.ServiceCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.Root, X509FindType.FindByIssuerName, "MailServer");
        ServiceDebugBehavior d = new ServiceDebugBehavior();
        d.IncludeExceptionDetailInFaults = true;
        host.Description.Behaviors.Remove<ServiceDebugBehavior>();
        host.Description.Behaviors.Add(d);
        ServiceMetadataBehavior b = new ServiceMetadataBehavior();
        b.HttpGetEnabled = true;
        host.Description.Behaviors.Remove<ServiceMetadataBehavior>();
        host.Description.Behaviors.Add(b);
        var mexBinding = MetadataExchangeBindings.CreateMexHttpBinding();
        host.AddServiceEndpoint(typeof(IMailServer), binding, "Service");
        host.AddServiceEndpoint(typeof(IMetadataExchange),mexBinding,"");


        host.Open();

クライアント構成:

           client = new MailServerReference.MailServerClient(new InstanceContext(this));

            client.ClientCredentials.UserName.UserName = currentUser.UserName;
            client.ClientCredentials.UserName.Password = currentUser.Password;
                client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
            client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.Root,X509FindType.FindByIssuerName, "MailServer");
            currentUser.ID = client.getUID();
            client.RegisterOnServer(currentUser.ID);
            return true;

        }
        catch (Exception ex) { MessageBox.Show(ex.Message); return false; }

どんな助けでも大歓迎です。ところで、私は WCF を初めて使用するので、基本的な概念が欠けている可能性があります。

4

1 に答える 1

0

クライアントとサーバーの両方でServiceCertificateandを同じものに設定してみます。ClientCertificate少なくとも、それは私がこれを行った方法です。しばらく経ちましたが、両方ではなく一方の証明書のみが設定されている場合に問題が発生したと思います。


追加情報を編集:

私の場合、 a のCustomBinding代わりに aを使用しWSDualHttpBindingますが、両方の側 (クライアントとサーバー) で ServiceCertificate と ClientCertificate にまったく同じ証明書を使用することになりました。

より具体的には、拡張するクラスがありますSystem.ServiceModel.Description.ServiceCredentials

public class MyServiceCredentials : ServiceCredentials
{
    public MyServiceCredentials() : base()
    {
        LoadCertificate();
    }

    public MyServiceCredentials(MyServiceCredentials other) : base(other)
    {
        LoadCertificate();
    }

    private void LoadCertificate()
    {
        ServiceCertificate.Certificate = _cert;
        ClientCertificate.Certificate = _cert;
        ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
        ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
   }
}

そして、クライアントとサーバーの両方の実装で、そのうちの 1 つを CustomBinding コンストラクターに渡します。

とにかく、Messageバインディングのセキュリティがオンになっているため、双方向にメッセージ レベルのセキュリティが期待されるため、両側 (ServiceCertificate と ClientCertificate) に証明書が必要だと思います。

私は完全に間違っている可能性があります。試してみて、それが役立つかどうかを確認してください...

于 2011-05-05T19:15:17.610 に答える