Reputation: 406
I am trying (desperately) to get a customer authentication provider working for my WCF service. So far I have the following code;
web.config
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyNamespace.CustomUserNameValidator, MyNamespace" />
</serviceCredentials>
<wsHttpBinding>
<binding name="wsHttpBindingConfig" >
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
Custom authenticator class;
public class CustomUserNameValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
// have security details been provided?
if (null == userName || null == password)
{
throw new ArgumentNullException();
}
// authenticate user
if (!(userName == "test" && password == "test"))
{
// This throws an informative fault to the client.
throw new FaultException("SecurityFailed");
}
}
}
Everything compiles ok, but when I use the WCF test client from visual studio to call a method called Ping (below), the custom authenticator never gets used. The Ping method just executes and any breakpoint I have in my CustomUserNameValidator class.
Why would this be? All help appreciated.
Upvotes: 0
Views: 2075
Reputation: 1722
I've taken all of the information that you've provided and created a template web.config. I would envision it looking something like this.
<system.serviceModel>
<services>
<service name="<YourNameSpace>.<ServiceName>" <behaviorConfiguration="<YourNameSpace>.<BehaviorName>">
<endpoint
address=""
binding="wsHttpBinding"
bindingConfiguration="wsHttpBindingConfig"
contract="<YourNameSpace>.<ServiceInterface>"
/>
<!--Notice the binding is mexHttpsBinding, default is http-->
<endpoint
address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="<YourNameSpace>.<BehaviorName>">
<!--Notice the httpsGetEnabled, default is http-->
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="<YourNameSpace>.CustomUserNameValidator, <YourNameSpace>"
/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingConfig">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
<wsHttpBinding>
</bindings>
Upvotes: 0
Reputation: 33260
In the line where you have
customUserNamePasswordValidatorType="MyNamespace.CustomUserNameValidator, MyNamespace"
the second part of the type (you currently have "MyNamespace") should be the name of the assembly containing the type, without any file extension.
See this question for more help.
Upvotes: 1
Reputation: 1722
A few suggestions.
When I use CustomAuthentication I set my binding up like this:
<wsHttpBinding>
<binding name="wsHttpBindingConfig" >
<security mode="TransportWithMessageCredentials">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
I assume you will like some form of security down the line. Testing with a self signed SSL cert on your machine pretty easy. There is more information about how to do this here.
Upvotes: 0