The WCF Service is a good thing, but every person in the network can use the service at will. This is a problem. This group of articles briefly lists several authentication methods. this article discusses certificate verification.
The use of X509 certificates for identity authentication should be the most "normal" Practice in the WCF security model, because WCF forces the use of certificates to encrypt identity data, leaving the certificate, all authentication mechanisms refuse to work, the identity authentication mechanism supported by WCF is also quite complex. Here, we only want to let the Program Act as we expected, so we do not discuss other verification methods. We have an approach as the basis, it is easy to find other implementation methods.
1. The software environment used in this article:
Windows 7
Visual Studio 2010
2. use vs to create a "WCF Service library" project. A default iservice1 interface and a default getdata function are generated. add a Windows Forms Application project in the current solution. As the test client of the service, add the service reference directly to the client and then discover it. service1 is displayed and confirmed directly.
3. write code now. Put a button on the form of the client, and write the call to the Service in the click event of this button:
var proxy = new ServiceReference1.Service1Client(); MessageBox.Show(proxy.GetData(0));
Set the client project as the starting project, run F5, and click:
4. after the test is completed, our basic environment has no problems. now we start to consider the issue of identity authentication. First, we use the user name/password mode for authentication. This requires a place to verify the user name and password: Add reference system in the service project. identitymodel, and then add a class to the service. The class is named validator. The implementation of this class is as follows:
class Validator : System.IdentityModel.Selectors.UserNamePasswordValidator { public override void Validate(string userName, string password) { if (userName != "u" || password != "p") throw new UnauthorizedAccessException(); } }
Right-click app. config of the Service Project and select Edit WCF configuration.
5. Create a binding configuration for the default endpoint.
Select the top-level node services in the list on the left, and the current endpoint will be listed on the right. There are two by default, and the following is the metadata endpoint. We don't care about it, the binding configuration of the endpoint above is followed by a "click to create" link. Click to automatically create a binding config. After creation, switch to the security label:
Change messageclientcredentialtype to username, as shown in.
6. Create a behavior for the service
As shown in:
By default, the advanced/service behaviors node in the left-side panel has an empty Name node. The node is named first. Here, a behavior suffix is added after the full name of the service, click Add to add a servicecredential node. then configure the new service credential:
Select servicecertificate under servicecredential in the list on the left, and configure the value as follows:
(1) Change findvalue to mytestcert. This is the name of the test certificate. We will create a certificate named later and import it to the computer.
(2) Change storename to trustedpeople
(3) Change x509findtype to findbysubjectname.
7. Use the validator class we just created
Select the servicecredential node and configure our custom verification class:
The value of the feature attribute is "feature, wcfservicelibrary3". The former wcfservicelibrary3 is the namespace name, and the latter is the set name, which cannot be omitted. Then, set usernamepasswordvalidationmode to custom.
8. Associate the created behavior with the service.
Select the service service1 we created in the left-side pane, and associate the configured service1behavior with it on the right side, so that the configuration of the entire server is complete.
After saving, the app. config is completed as follows:
<?xml version="1.0" encoding="utf-8" ?><configuration> <system.web> <compilation debug="true" /> </system.web> <!-- When deploying the service library project, the content of the config file must be added to the host's app.config file. System.Configuration does not support config files for libraries. --> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="NewBinding0"> <security> <message clientCredentialType="UserName" /> </security> </binding> </wsHttpBinding> </bindings> <services> <service behaviorConfiguration="WcfServiceLibrary3.Service1Behavior" name="WcfServiceLibrary3.Service1"> <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBinding0" contract="WcfServiceLibrary3.IService1"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
9. Create a certificate and import it.
Choose Start> Microsoft Visual studio2010> Visual Studio Tools, click Visual Studio command prompt, open the command line window, and enter the following command:
Makecert-r-pe-n "cn = mytestcert"-SS trustedpeople-Sr localmachine-sky exchange
10. Now run F5 again. When you click button 1 again, the following exception is thrown:
Now we can confirm that it is impossible for the client to use the service anonymously, and then configure the credential for the client.
Right-click the app. config of the client and select Edit WCF configuration.
11. Create an endpoint behavior.
Create an endpoint behavior under advanced/Endpoint behavior:
Click Add to add a clientcredential node.
Expand its servicecertificate node, select defaultcertificate, and edit its attributes, such:
The values are consistent with those on the server.
12. Bind this behavior to the endpoint
13. Specify DNS
Switch to the identity tag and specify the DNS attribute as our Certificate Name:
At this point, all client configurations are completed. The final app. config code of the client is:
<?xml version="1.0" encoding="utf-8" ?><configuration> <system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="NewBehavior0"> <clientCredentials> <serviceCertificate> <defaultCertificate findValue="MyTestCert" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" /> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Message"> <message clientCredentialType="UserName" negotiateServiceCredential="true" algorithmSuite="Default" /> </security> </binding> </wsHttpBinding> </bindings> <client> <endpoint address="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary3/Service1/" behaviorConfiguration="NewBehavior0" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1" name="WSHttpBinding_IService1"> <identity> <dns value="MyTestCert" /> </identity> </endpoint> </client> </system.serviceModel></configuration>
14. Specify the user name and password.
Change the client button code:
private void button1_Click(object sender, EventArgs e) { var ser = new ServiceReference1.Service1Client(); ser.ClientCredentials.UserName.UserName = "u"; ser.ClientCredentials.UserName.Password = "p"; MessageBox.Show(ser.GetData(0)); }
When F5 is run, the correct result is returned. If the user name and password are incorrect, an exception is thrown: