TA123

Hi All,

I am using Microsoft's WCF usernamepasswordvalidator sample.

It works fine on my system using test certificate.

After achieving this, I removed the generated proxy and created my own by enabling metadata in service.Now when I run it, it gives the following error inside the innerexception section:

"The X.509 certificate CN=localhost chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider."

I even tried to use following code in the client to remove this error but of no use.

PermissiveCertificatePolicy.Enact("CN=localhost");

class PermissiveCertificatePolicy

{

string subjectName;
static PermissiveCertificatePolicy currentPolicy;
PermissiveCertificatePolicy(string subjectName)
{this.subjectName = subjectName;
ServicePointManager.ServerCertificateValidationCallback +=
new System.Net.Security.RemoteCertificateValidationCallback(RemoteCertValidate);
}

public static void Enact(string subjectName)

{currentPolicy = new PermissiveCertificatePolicy(subjectName);}
bool RemoteCertValidate(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)

{
if (cert.Subject == subjectName)
{return true;}
return false;}}

Can anybody please guide me on how to resolve this issue. If needed, I have pasted the service appp.config below

<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<services>
<service behaviorConfiguration="CalculatorServiceBehavior" name="Microsoft.ServiceModel.Samples.CalculatorService">
<endpoint address="Username" binding="wsHttpBinding" bindingConfiguration="Binding1"
name="" contract="Microsoft.ServiceModel.Samples.ICalculator" />
<host>
<baseAddresses>
<add baseAddress="
http://localhost:8001/servicemodelsamples/service" />
</baseAddresses>
</host>
</service>
</services>

<bindings>
<wsHttpBinding>
<!-- Username binding -->
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceCredentials>
<serviceCertificate findValue="localhost" storeLocation="CurrentUser"
storeName="My" x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.CalculatorService+CustomUserNameValidator, service" />
</serviceCredentials>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

regards



Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

leo2

Hi Guys,

I am finally able to solve this problem.And for others sake, here is the solution.

As per my understanding, at the service end, you have to create a service behavior-> And under Service Credentials set serviceCertificate.

 Now after creating an proxy out of this for client usage using svcutil, we will get one app.config for client usage.

Open that again in the svcconfigeditor , now create a endpoint behavior ->  And then under ClientCredentials- >Client certificate ->Authentication set CertificateValidationMode to PeerOrChainTrust.

I did this and the example is ran successfully but still can't understand two things:

1) Why i had to make some changes in client side.Can't we do something addtitional in service side so that the generated app.config can be readily used.

2)When we look into the advaced Folder(in the last of the tree) in SvcconfigEditor, entries are somewhat confusing.Can somebody please make me understand about different between endpoint behavior and service behavior and inside these both service and clientcredential exists both of which in turn again have both client and service certificate.what is to be set in which case.Somebody please elaborate on this

Regards





Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

pyeung

Hi Leo2

Certificate issues are quite complicated. I attempt to share some of my view with you but is not guaranteed to be very accurate.

The error message you encountered is obviously because you did not add the public key of your issuing authority to your machine's "Trusted Root Certificate Authority" store. So, your machine does not trust that it is a valid key. The reason why the sample key is OK is that it is issued by some authority trusted by your machine (I did not try your sample, but I think the key might be issued by Microsoft. Windows O/S added Microsoft Root Authority as trusted root during windows installation.)






Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

TrevorW

I think the issue is PeerOrChain trust. If auto-generated proxies allowed certificates to pass without verifying that they from an authenic authority, then security would go 'poof'. (so PeerOrChain trust in not auto-generated)

So, while testing with a fake certificate that is not issued by a real authority, expect to manually deal with this. If you want to eliminate the problem, use a real certificate that would pass with Chain only.

*I am no certificate expert, but that seems logical to me.

Trevor





Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

leo2

thanks to both of your for loking into my problem but please try to answer my two queries whcih i have written in the last

1) Why i had to make some changes in client side.Can't we do something addtitional in service side so that the generated app.config can be readily used.

2)When we look into the advaced Folder(in the last of the tree) in SvcconfigEditor, entries are somewhat confusing.Can somebody please make me understand about different between endpoint behavior and service behavior and inside these both service and clientcredential exists both of which in turn again have both client and service certificate.what is to be set in which case.Somebody please elaborate on this

regards





Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

pyeung

Hi Leo2

1) You can set negotiateServiceCredential to true on the WCF host. Proxies generated from these hosts will automatically include the public key. As a result, you do not need to do anything in the Client Certificate store.

2) A service can have many endpoints. So service behavior affects all the endpoints belonging to this service. Endpoint behavior affects only a particular endpoints.

Correct me if I am wrong.






Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

leo2

Hi pyeung,

Thanks for your reply.

1) ichecked in my example and found that

what you are telling is section below and indeed genearted automatically when we create client proxy using svcutil:

<endpoint address="http://localhost:8001/servicemodelsamples/service/Username"

behaviorConfiguration="ClientCertificateBehavior" binding="wsHttpBinding"

bindingConfiguration="WSHttpBinding_ICalculator" contract="ICalculator"

name="WSHttpBinding_ICalculator">

<identity>

<certificate encodedValue="AwAAAAEAAAAUAAAASiJwSewea9toFYn8gSSfVCEUyWcgAAAAAQAAALUBAAAwggGxMIIBX6ADAgECAhDEWVXt4HI8jE1Nd4yh/NfQMAkGBSsOAwIdBQAwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3kwHhcNMDcwMzA5MDczOTI2WhcNMzkxMjMxMjM1OTU5WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM9LjeOHVIKUsU1FTZjwF4FdCzsmE4SGB7Xp+hIsDGfsQp71+6ny+8PzaVSPky1aNBNtlhbKPQXKMmBobGyntzvG6fpdJCPvMaOSMSlG2r9ywUWEtkeLfV3HNg/sIAHiT7yX/2PHLjrJJTZIw2tfC2ml9nLjfaPJJStmyZOENg2tAgMBAAGjSzBJMEcGA1UdAQRAMD6AEBLkCS0GHR1PAI1hIdwWZGOhGDAWMRQwEgYDVQQDEwtSb290IEFnZW5jeYIQBjdsAKoAZIoRz7jUqlw19DAJBgUrDgMCHQUAA0EAfdiVoMJFcJABwJtGdKZGvo0y1lNVcrknKa0+l4aoUt8GGR53V63ezHiT0ElaL2RXOp44Gydn1n25afpFLobPXw==" />

</identity>

</endpoint>

However the section which i need to be generated automatically for client end is below

<behaviors>

<endpointBehaviors>

<behavior name="ClientCertificateBehavior">

<clientCredentials>

<serviceCertificate>

<authentication certificateValidationMode="PeerOrChainTrust" />

</serviceCertificate>

</clientCredentials>

</behavior>

</endpointBehaviors>

</behaviors>

Can you please help me in getting this.

2) I think what you have responded for this is correct as i saw that we generally need to configure endpoint behavior only at the client side.

Cheers





Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

pyeung

Hi Leo2

If your negotiateServiceCredential is set to false, I don't think your can work without a public key on the client side because signing and encryption requires it.

I suggest you try your tests on two PCs, one as server and the other as client. If you test it on a single PC, there is chance that the client is using the server certificate.






Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

leo2

Hi,

As i wrote before, you are correct about certificate using negotiateservicecredential. However the section which i need to be generated automatically for client end is below

<behaviors>

<endpointBehaviors>

<behavior name="ClientCertificateBehavior">

<clientCredentials>

<serviceCertificate>

<authentication certificateValidationMode="PeerOrChainTrust" />

</serviceCertificate>

</clientCredentials>

</behavior>

</endpointBehaviors>

</behaviors>

This section don't gets generated automatically regardless of whether client is on the same machine as service or on a different machine. Can you please help me in getting this.

Cheers





Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

TrevorW

I may be wrong... but... unless you are in control of the client - I don't think you can. If you could, that would be really, really bad (IMO)

Think about why

If a service can force a client to accept certificates without verifying that they are valid (I.e. remove the security check to the CA (certificate authority), then security goes - POOF!

Just my opinion.

If you control the client application, then I would add something on the client side to check the service on whether to downgrade security, auto-try again, or whatever you imagine. Again, I think it would be very bad to allow a service to force a client to accept downgrades in security levels because I could then inject my own "fake" service with downgraded WSDL's and start hacking from there.

Trevor





Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

leo2

hi trevor,

I might be wrong in what i am going to write.So please correct if it is so
Ya but i think you are referening to suing peerorchainrequest for security hazard to client.
Otherwise if i change i to chaintrust, do you still think that the xml code i posted in my
last post is really anything to do with client safety.
As you can see that it is clientcredentials tag, so meant for client validation
at service end.So it is not forcing client to accept service certificates.Instead
it is for service use to check client certificate

Am i wrong in this as i am not sure about it.

One more thing if you can help

I want to use message security with username as the identity and certificate for transport security(hence want to use https).
My service is self hosted(i have set it using httpcfg ) and not IIS hosted. I want to use wshttpbinding but want to secure the endpoint (i am not sure as what is needed to secure an endpint and how it is different from using https).
Believe me i have tried enough to make it run but in vain.


< xml version="1.0" encoding="utf-8" >
<!--
   Copyright (c) Microsoft Corporation.  All rights reserved.
-->
<configuration>

  <system.diagnostics />
  <system.serviceModel>
    <diagnostics>
      <messageLogging logEntireMessage="true" logMalformedMessages="true"
        logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
    </diagnostics>
    <services>
      <service behaviorConfiguration="CalculatorServiceBehavior" name="Microsoft.ServiceModel.Samples.CalculatorService">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1"
          name="Username" contract="Microsoft.ServiceModel.Samples.ICalculator" />
        <endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration=""
          contract="IMetadataExchange">
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="
https://localhost:8001/servicemodelsamples/service" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <bindings>
      <wsHttpBinding>
        <binding name="Binding1">
          <reliableSession enabled="false" />
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" proxyCredentialType="None" />
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="CurrentUser"
              storeName="TrustedPeople" x509FindType="FindBySubjectName" />
            <userNameAuthentication userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.CalculatorService+CustomUserNameValidator, service" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
   
  </system.serviceModel>

</configuration>

Can you please help me in how to resolve this issue





Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

TrevorW

The problem is that you are using a fake service certificate for testing (I assume you are). You need a certificate issued by a certificate authority. Here si where you told WCF to use a certificate for the service:

<serviceCredentials>
<serviceCertificate findValue="localhost" storeLocation="CurrentUser"
storeName="TrustedPeople" x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.CalculatorService+CustomUserNameValidator, service" />
</serviceCredentials>

The client will normally require that a certificate is verified against a certificate authority (Chain trust), but the certificate is "fake" and is not issued by a certificate authority: you created it.

Now you have this too:

<services>
<service behaviorConfiguration="CalculatorServiceBehavior" name="Microsoft.ServiceModel.Samples.CalculatorService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1"
name="Username" contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration=""
contract="IMetadataExchange">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="
https://localhost:8001/servicemodelsamples/service
" />
</baseAddresses>
</host>
</service>

This part requires that your service only share endpoint information via a secure connection:

<endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration=""
contract="IMetadataExchange">

Drop that out of your config file (*Note - I don't use MEX or wsHTTP, so I may be wrong, what I will suggest works with TCP connections)

Add this just below your serviceCredentials section:

<serviceMetadata httpGetUrl=http://localhost:8002/servicemodelsamples/service httpGetEnabled="true"/>

Now, your service should host unsecured WSDL (service metadata) info for the service on port 8002 and your actual secured service on port 8001

*You are also probably able to modify the mex binding to be http instead of https, but you would likely need to specify the full http (not https) address instead of just "mex" because I 'think' it would also have to be on a separate port due to the difference in security settings. Since, I don;t use mex or http, I can be wrong.

You could also change your service to use a netTcpBinding unless you need the soap headers for some purpose.

Anyway, your client can't access the secured https mex port because it needs the service certificate info for encryption and it fails because its not from a CA.

So, what I suggested is to publish the WSDL on an unsecured port and the service on a secured port.... or... use a real certificate because I think it would work with a real cert.

Again, I am not an expert and I am just trying to help.

Trevor





Re: Windows Communication Foundation (Indigo) wcf user/pass cetificate issue

pyeung

Hi Leo

TrevorW is correct. You cannot automatically generate certificateValidationMode for client because it depends on the degree of trust that client placed on your service. If your service is on the intranet, the trust level can be higher. If it is on internet, the trust level is probably lower.