I fallowed a tutorial to secure wcf service with username and password, and with certificate.
I created and install certificate using pluralsight's self-Cert tool. and override validate method which is inherit from UserNamePasswordValidator. Certificate security is working fine, but validate method is not invoking during a service call. Service can be accessed without a providing username and password.
I read many articles about it, but the same procedure is shown there. I also read other stack overflow question about same problem but i am unable to find the solution for it.
Validation Code
using System;
using System.IdentityModel.Selectors;
using System.ServiceModel;
namespace WcfSecure
{
public class CredentialValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (userName == null && password == null)
throw new ArgumentNullException();
if (!(userName == "one" && password == "two"))
throw new FaultException("Wrong Credentials!");
}
}
}
Here Service Contract.
using System.ServiceModel;
namespace WcfSecure
{
[ServiceContract]
public interface ISecureWebService
{
[OperationContract]
int SecureAdd(int x, int y);
[OperationContract]
int UnSecureService(int x, int y);
}
}
Service Code
namespace WcfSecure
{
public class SecureWebService : ISecureWebService
{
public int SecureAdd(int x, int y)
{
return x + y;
}
public int UnSecureService(int x, int y)
{
return x + y;
}
}
}
And the most important Web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="SecureBinding">
<security mode="Message">
<message clientCredentialType="UserName" establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors >
<behavior name="CustomBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="SecureService"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName"/>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfSecure.CredentialValidator, WcfSecure" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="CustomBehavior" name ="WcfSecure.SecureWebService">
<endpoint address="" binding="wsHttpBinding" contract="WcfSecure.ISecureWebService"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://192.168.1.224:84/WcfSecure/SecureWebService"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>