Sometimes, we want to expose some API (services) publicly. In order to secure the service, we can go with standard user name/password authentication. We can also add extra security by validating client IP. Services can also be secured by enabling X509 Certificate authentication if it is meant for closed user group or few partners. There are many other options to secured the services.
RESTFull service that is hosted on IIS.
Here are the steps:
- Create certificates
- Configure the web.config
- Configure the IIS
- Sample client application
1. Create certificates
Ideally the certificates should be obtained from the trusted certificate authority. But in the development environment, we can create it using makecert.exe that comes with Visual Studio.
We need one certificate for the server and one certificate for each unique client. For this example, we will create two certificates one for the server and one for the client. Visit here to know more about makecert.exe.
makecert -sv srvr.pvk srvr.cer -n CN=testServer
makecert -sv client1.pvk client1.cer -n CN=testClient1
Generate Pfx file from pvk file. Visit here for more.
pvk2pfx -pvk srvr.pvk -pi password -spc srvr.cer -pfx srvr.pfx
pvk2pfx -pvk client1.pvk -pi password -spc client1.cer -pfx client1.pfx
In the server:
Import srvr.pfx into LocalMachine -> Personal, Certificates
Import client1.cer into LocalMachine -> Trusted People, Certificates
In the client
Import client1.pfx into LocalMachine -> Personal, Certificates
We might have to import both the files in the systems' LocalMachine -> Trusted Root Certificate Authorities. This is not required in case of valid certificates.
2. Configure the web.config
Once the certificates are ready, we have to configure the WCF service to set security mode is Transport and client credential type is Certificate as mentioned below:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webSecureBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="securedBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="RestServerWcf.Service" behaviorConfiguration="securedBehavior">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="webSecureBinding" behaviorConfiguration="webBehavior" contract="RestServerWcf.IService"/>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webSecureBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="securedBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="RestServerWcf.Service" behaviorConfiguration="securedBehavior">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="webSecureBinding" behaviorConfiguration="webBehavior" contract="RestServerWcf.IService"/>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
3. Configure the IIS
We also have to configure IIS for SSL (https). First lets add new binding for https. Open the IIS, select the web site and click on Bindings at right hand side:
Add new binding:
Configure SSL Settings, click on SSL Settings:
And finally set the Require SSL:
Add new binding:
Configure SSL Settings, click on SSL Settings:
And finally set the Require SSL:
4. Sample client application
Once, we are done with all the configuration then lets build sample client application to consume the services// Generate request HttpWebRequest request = WebRequest.Create(@"https://server/service.svc/json/customers") as HttpWebRequest; // Find the certificate from the local store X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = store.Certificates.Find(X509FindType.FindBySubjectName, "Client", false); X509Certificate cer1 = new X509Certificate(collection[0]); // Add the certificate into the request request.ClientCertificates.Add(cer1); // Hit the service and get the response HttpWebResponse response = (HttpWebResponse)request.GetResponse();Done.