views:

3466

answers:

2

Hi,

First of all I apologize for my english...

Then: I have a problem!

I wrote the code for a simple WCF Service and with the configuration #1 all works fine.

Conf #1 - server

<configuration>
  <system.serviceModel>
    <services>
      <service name="WCFservice.Service" 
               behaviorConfiguration="WCFservice.ServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8731/WCFservice/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="WCFservice.IService"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="WSCertificateSecurity">
          <reliableSession enabled="true"/>
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFservice.ServiceBehavior">
          <serviceCredentials>
            <serviceCertificate findValue="cn=abc" 
                    storeLocation="LocalMachine" storeName="TrustedPeople" 
                    x509FindType="FindBySubjectDistinguishedName"/>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Conf #1 - client

<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService">
          <reliableSession enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" 
                       proxyCredentialType="None" realm="" />
            <message clientCredentialType="Windows" 
                  negotiateServiceCredential="true"
                  establishSecurityContext="true" 
                  algorithmSuite="Default" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8731/WCFservice/" 
                binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IService" 
                contract="WCF.IService"
                name="WSHttpBinding_IService">
        <identity>
          <userPrincipalName value="myname" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

The problem occurs when I try to set userName authentication with a personal validation class I created. I post configuration #2.

Conf #2 - server

<configuration>
  <system.serviceModel>
    <services>
      <service name="WCFservice.Service" 
               behaviorConfiguration="WCFservice.ServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8731/WCFservice/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="WCFservice.IService"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="WSCertificateSecurity">
          <reliableSession enabled="true"/>
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFservice.ServiceBehavior">
          <serviceCredentials>
            <userNameAuthentication 
                 userNamePasswordValidationMode="Custom"  
                 customUserNamePasswordValidatorType="WCFservice.Login, WCFservice"/>
            <serviceCertificate findValue="cn=abc" 
                 storeLocation="LocalMachine" storeName="TrustedPeople" 
                 x509FindType="FindBySubjectDistinguishedName"/>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Conf #2 - client

<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService">
          <reliableSession enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" 
                  proxyCredentialType="None" realm="" />
            <message 
                  clientCredentialType="UserName" 
                  negotiateServiceCredential="true"
                  establishSecurityContext="true" 
                  algorithmSuite="Default" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8731/WCFservice/" binding="wsHttpBinding"
        bindingConfiguration="WSHttpBinding_IService" contract="WCF.IService"
        name="WSHttpBinding_IService">
        <identity>
          <userPrincipalName value="myname" />
        </identity>
      </endpoint>
    </client>

When I start the application and I get a

System.ServiceModel.Security.SecurityNegotiationException

private void button1_Click(object sender, EventArgs e) 
{
    WCF.XnottaLightServiceClient client = new WCF.XnottaLightServiceClient();
    client.ClientCredentials.UserName.UserName = "user";
    client.ClientCredentials.UserName.Password = "pass";

    string[] s = textBox6.Text.Split('§');
    int[] i = new int[s.Length];
    for(int j = 0; j < i.Length; j++) 
    {
        i[j] = Convert.ToInt32(s[j]);
    }

    string string1 = client.getString("xnl");
}

Any ideas?

Thanks, Alberto

+2  A: 

Well, one thing that immediately sticks out is this discrepancy:

Server:

<wsHttpBinding>
        <binding name="WSCertificateSecurity">
          <reliableSession enabled="true"/>

Reliable sessions is enabled = true.

Client:

<wsHttpBinding>
        <binding name="WSHttpBinding_IService">
          <reliableSession enabled="false" />

Reliable sessions is enabled = false.

This is definitely a mismatch - surprisingly, though, this is the case in both your #1 and #2 scenarios.....

Marc

marc_s
A: 

Thanks for the correction, I would assign a point if I could (I don't have the minimum reputation for voting...)

If you want, check out my question: http://stackoverflow.com/questions/949026/wcf-service-security-for-authentication-and-authorization

It's a generalization of the one above...

Thanks,

Alberto

Alberto