1. 程式人生 > >使用wsHttpBinding構建Message安全模式和UserName授權

使用wsHttpBinding構建Message安全模式和UserName授權

http://www.cnblogs.com/artech/archive/2011/05/22/authentication_01.html

https://www.cnblogs.com/Frank-yafeya/p/3283699.html

https://www.cnblogs.com/jfzhu/p/4067873.html

https://www.cnblogs.com/niaowo/p/4727378.html

1. server 

 a. implement UserNaePasswordValidator

using System;
using System.Collections.Generic;
using System.Linq; using System.Web; using System.IdentityModel.Selectors; using System.ServiceModel; namespace WcfService1.Common { public class CustomUserNameValidator : UserNamePasswordValidator { public override void Validate(string userName, string password) {
if (userName != "admin" || password != "abc123") { throw new FaultException("UserName or Password is incorrect!"); } } } }

b. generate certificate

makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=WcfServerCert -sky exchange –pe

c. config

<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.7" />
    <httpRuntime targetFramework="4.7"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WcfService1.Service1" behaviorConfiguration="securityBehaviorConfig">
        <endpoint address="" binding="wsHttpBinding" contract="WcfService1.Contract.IService1" 
                  bindingConfiguration="wsBindingConfig" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/wcf/Service1" />
          </baseAddresses>
        </host>
      </service>
      <service name="WcfService1.UserService">
        <endpoint address="" behaviorConfiguration="WcfService1.UserServiceAspNetAjaxBehavior"
          binding="webHttpBinding" contract="WcfService1.UserService" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="WcfService1.UserServiceAspNetAjaxBehavior">
          <webHttp  />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
        <behavior name="securityBehaviorConfig">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <serviceCertificate findValue="WcfServerCert" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
            <userNameAuthentication
              userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="WcfService1.Common.CustomUserNameValidator, WcfService1"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="wsBindingConfig">
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
  </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>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true" >
        <listeners>
          <add name="xml"/>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="xml"/>
        </listeners>
      </source>
      <source name="myUserTraceSource"
              switchValue="Information, ActivityTracing">
        <listeners>
          <add name="xml"/>
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="xml"
           type="System.Diagnostics.XmlWriterTraceListener"
           initializeData="Error.svclog" />
    </sharedListeners>
  </system.diagnostics>
</configuration>

certlm.msc 新增 IIS AppPool\AppPoolName帳號,替換AppPoolName為應用池的名稱,這裡為WCFDemo。

 

2. client 

         var wsBinding = new WSHttpBinding();
            wsBinding.Security.Mode = SecurityMode.Message;
            wsBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
// for exception: Identity check failed for outgoing message. The expected DNS identity of the remote endpoint was 'localhost' but the remote endpoint provided DNS EndpointIdentity identity
= EndpointIdentity.CreateDnsIdentity("WcfServerCert"); EndpointAddress endAddress = new EndpointAddress(new Uri("http://localhost/wcf/Service1.svc"), identity); using (var factory = new ChannelFactory<IService1>(wsBinding, endAddress)) { factory.Credentials.UserName.UserName = "admin"; factory.Credentials.UserName.Password = "abc123"; factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; var proxy = factory.CreateChannel(); string result = proxy.GetData(8); Console.WriteLine(result); }