Link to home
Start Free TrialLog in
Avatar of shekhar_shashi
shekhar_shashi

asked on

WCF Security

I hate to post long messages on a disucssion forum but I dont think I have an option here.

I have a simple "Hello World" WCF service and a simple winform client. Everything is built using VS 2010 and .Net 4.0 and all applications run locally on my WinXP desktop.

My experiment is based on this link.
http://blogs.msdn.com/b/pedram/archive/2007/10/05/wcf-authentication-custom-username-and-password-validator.aspx

So I was trying to build this WCF service using custom authentication and self signed certificate.

The service app.config file reads.
...
<system.serviceModel>
      <diagnostics>
        <messageLogging logEntireMessage="true" logMalformedMessages="false" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false" maxMessagesToLog="3000" maxSizeOfMessageToLog="2000"/>
      </diagnostics>
      <behaviors>
        <serviceBehaviors>
          <behavior name="CreditCardServiceBehavior">
            <serviceMetadata httpGetEnabled="true"/>
          </behavior>
          <behavior name="CustomValidator">
            <serviceCredentials>
              <serviceCertificate findValue="CIS525" storeLocation="CurrentUser" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
              <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CreditcardValidationService.CIS525Authenticator, CreditcardValidationService"/>
            </serviceCredentials>
            <serviceMetadata/>
          </behavior>
        </serviceBehaviors>
      </behaviors>
        <services>
            <service behaviorConfiguration="CustomValidator" name="CreditcardValidationService.ValidateCreditCardService">
                <endpoint address="base" binding="wsHttpBinding" bindingConfiguration=""
                    contract="CreditcardValidationService.ICreditcardValidationService" />
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8080/CreditCardValidationService" />
                    </baseAddresses>
                </host>
            </service>
        </services>
      <bindings>
        <wsHttpBinding>
          <binding name="httpWithMessageSecurity">
            <security mode="None" >
              <message clientCredentialType="UserName"/>
            </security>
          </binding>
        </wsHttpBinding>
      </bindings>
        <client/>
    </system.serviceModel>
....


The client app.config reads:
    <system.serviceModel>
        <diagnostics>
            <messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"/>
        </diagnostics>
        <bindings>
          <wsHttpBinding>
                <binding name="wsHttpBinding_ICreditcardValidationService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
                     <security mode="Message" >
                    <message clientCredentialType="UserName"/>
                  </security>
                </binding>
            </wsHttpBinding>
         </bindings>
        <client>
          <endpoint address="http://localhost:8080/CreditCardValidationService/base" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_ICreditcardValidationService" contract="ValidateCreditCardServiceReference.ICreditcardValidationService" name="wsHttpBinding_ICreditcardValidationService">
            <identity>
              <dns value="CIS525"/>
            </identity>
          </endpoint>
        </client>
    </system.serviceModel>

I installed a self signed certificate in Trusted People store and also in trusted root certification authorities. Windows recognizes my certificate as valid when I open the certificate file.

My custom validator is like this.

namespace CreditcardValidationService
{
    public class CIS525Authenticator : UserNamePasswordValidator
    {

    public override void Validate(string userName, string password)

    {
        //check for null user name and password
        if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))

            throw new SecurityTokenException("Username and password required");
    }

}

}

When I call my service from the client application, I get this error:
Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint.

I dont know what I am doing wrong. Please help.

ASKER CERTIFIED SOLUTION
Avatar of shekhar_shashi
shekhar_shashi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial