开发者

WCF wsdualhttpBinding custom username

I'v got very annoying error: My scenario - simple message/mail server\client implemented in WCF with wsdualhttpbinding (dual for callbacks , online update on new message).

All security config is written in code (no *.config at all) . Upon first connection the client throws the following [System.Security.Cryptography.CryptographicException] = {"Bad Length.\r\n"} with NULL inner exception , so drilling deeper isn't possible . Server configuration :

     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 configuration :

           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 = clien开发者_开发知识库t.getUID();
            client.RegisterOnServer(currentUser.ID);
            return true;

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

Any help would be very much appreciated.And BTW I am new to WCF , so maybe I am missing some basic concept .


I would try setting the ServiceCertificate and ClientCertificate to the same thing on both the client and the server. At least, that is the way I've done this. It has been a while, but I think I had issues when only one certificate or the other was set, and not both.


Edit for additional info:

In my case, I use a CustomBinding instead of a WSDualHttpBinding but I ended up using the exact same certificate for the ServiceCertificate and ClientCertificate on both sides (client and server).

More specifically, I have a class that extends 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;
   }
}

And I pass one of those to my CustomBinding constructor in both the client and server implementation.

Anyway, I think because Message security is turned on for the binding, it expects there to be message level security in both directions, so it needs a certificate on both sides (ServiceCertificate and ClientCertificate).

I could be completely wrong though, I'm just saying; try it and see if that helps...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜