WCF 使用证书认证 方法

1、 打开 VS2010 Prompt  工具,创建证书。

    输入以下命令:

makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=localhost -sky exchange -pe

certmgr.exe -add -r LocalMachine -s My -c -n localhost -r CurrentUser -s TrustedPeople

2、设置证书访问权限

按照下面的步骤可解决 IIS7 Keyset does not exist 的问题, 根源为权限问题

1:运行 输入 mmc
2:Console -> file->add/remove snap/in
3:弹出的界面左边第三项:certificates-> add
3:弹出的界面选择computer Account 下一步第一个项 ok。
4:certificates下面找到 Personal certificates 右边 可以找到你创建的证书
5:最关键的一步:右击证书->All tasks-> manager private keys->在谈出的security中加入 everyone  full control

3、创建项目

3.1 项目结构

  

  3.2  服务端代码(service.cs)

View Code
//  Copyright (c) Microsoft Corporation.  All Rights Reserved.

using System;
using System.ServiceModel;


namespace Microsoft.ServiceModel.Samples
{
    // Define a service contract.
    [ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        bool IsCallerAnonymous();
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
    }

    // Service class which implements the service contract.
    // Added code to return whether the caller is anonymous
    public class CalculatorService : ICalculator
    {
        public bool IsCallerAnonymous()
        {
            // ServiceSecurityContext.IsAnonymous returns true if the caller is not authenticated
            return ServiceSecurityContext.Current.IsAnonymous;
        }

        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            return result;
        }

        public double Subtract(double n1, double n2)
        {
            double result = n1 - n2;
            return result;
        }

        public double Multiply(double n1, double n2)
        {
            double result = n1 * n2;
            return result;
        }

        public double Divide(double n1, double n2)
        {
            double result = n1 / n2;
            return result;
        }
    }

}

 3.3 服务端(service.svc)

<%@ServiceHost language=c# Debug="true" Service="Microsoft.ServiceModel.Samples.CalculatorService" %>

  3.4 客户端代码(client.cs)

View Code
//  Copyright (c) Microsoft Corporation.  All Rights Reserved.

using System;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples
{
    //The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.

    //Client implementation code.
    class Client
    {
        static void Main()
        {
            // Create a client with given client endpoint configuration
            CalculatorClient client = new CalculatorClient();

            // Call the GetCallerIdentity operation
            Console.WriteLine("IsCallerAnonymous returned: {0}", client.IsCallerAnonymous());

            // Call the Add service operation.
            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

            // Call the Subtract service operation.
            value1 = 145.00D;
            value2 = 76.54D;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

            // Call the Multiply service operation.
            value1 = 9.00D;
            value2 = 81.25D;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

            // Call the Divide service operation.
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

            //Closing the client gracefully closes the connection and cleans up resources
            client.Close();

            Console.WriteLine();
            Console.WriteLine("Press <ENTER> to terminate client.");
            Console.ReadLine();
        }
    }
}

3.5、 设置WCF 项目中的(服务端)配置文件

            <?xml version="1.0" encoding="utf-8" ?>
            <configuration>
              <system.serviceModel>
                <services>
                  <service name="Microsoft.ServiceModel.Samples.CalculatorService"
                           behaviorConfiguration="CalculatorServiceBehavior">
                    <!-- this endpoint is exposed at the base address provided by host: http://localhost/servicemodelsamples/service.svc  -->
                    <endpoint address=""
                      binding="wsHttpBinding"
                      bindingConfiguration="Binding1" 
                      contract="Microsoft.ServiceModel.Samples.ICalculator" />
                    <!-- the mex endpoint is exposed at http://localhost/servicemodelsamples/service.svc/mex -->
                    <endpoint address="mex"
                              binding="mexHttpBinding"
                              contract="IMetadataExchange" />
                  </service>
                </services>

                <bindings>
                  <wsHttpBinding>
                    <!-- 
                    This configuration defines the security mode as Message and 
                    the clientCredentialType as None.
                    This mode provides server authentication only using the service certificate.
                    -->
                    <binding name="Binding1">
                      <security mode = "Message">
                        <message clientCredentialType="None"/>
                      </security>
                    </binding>
                  </wsHttpBinding>
                </bindings>

                <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
                <behaviors>
                  <serviceBehaviors>
                    <behavior name="CalculatorServiceBehavior">
                      <!-- 
                    The serviceCredentials behavior allows one to define a service certificate.
                    A service certificate is used by a client to authenticate the service and provide message protection.
                    This configuration references the "localhost" certificate installed during the setup instructions.
                    -->
                      <serviceCredentials>
                        <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
                       
                      </serviceCredentials>
                    
                      <serviceMetadata httpGetEnabled="True"/>
                      <serviceDebug includeExceptionDetailInFaults="False" />
                    </behavior>
                  </serviceBehaviors>
                </behaviors>
              </system.serviceModel>
            </configuration>

3.6、设置客户端(App.Config)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint name=""
                address="http://localhost/TestService/service.svc" 
                binding="wsHttpBinding" 
                behaviorConfiguration="ClientCredentialsBehavior"
                bindingConfiguration="Binding1" 
                contract="Microsoft.ServiceModel.Samples.ICalculator" />
    </client>

    <bindings>
      <wsHttpBinding>
        <!-- 
        This configuration defines the security mode as Message and 
        the clientCredentialType as None.
        -->
        <binding name="Binding1">
          <security mode = "Message">
            <message clientCredentialType="None"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <endpointBehaviors>
        <behavior name="ClientCredentialsBehavior">
          <clientCredentials>
            <serviceCertificate>
              <!-- 
            Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate 
            is in the user's Trusted People store, then it will be trusted without performing a
            validation of the certificate's issuer chain. This setting is used here for convenience so that the 
            sample can be run without having to have certificates issued by a certificate authority (CA).
            This setting is less secure than the default, ChainTrust. The security implications of this 
            setting should be carefully considered before using PeerOrChainTrust in production code. 
            -->
              <authentication certificateValidationMode="PeerOrChainTrust" />
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>


本示例提供代码下载

原文地址:https://www.cnblogs.com/tianjinquan/p/2645019.html