天天看點

siverlight+wcf(basicHttpBinding)自定義使用者名密碼驗證

一:建立證書

        使用vs的指令建立

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

二:wcf服務

     由于siverlight支援綁定限制,是以這裡使用basicHttpBinding

     主要是配置檔案

<?xml version="1.0" encoding="utf-8"?>
<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>
    
    <behaviors>
      <serviceBehaviors>
        <behavior name="mybehavior">
          <serviceMetadata  httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />

          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="None"/>
            </clientCertificate>
            
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfCertificate.Validator,WcfCertificate" />
            <serviceCertificate storeLocation="LocalMachine" storeName="My" findValue="TestServer" x509FindType="FindBySubjectName" />
          </serviceCredentials>         
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <!--指定驗證方式-->
     <bindings>
       <basicHttpBinding>
        <binding name="myhttpbind">
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="Windows"/>
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>

      <service name="WcfCertificate.Service1"  behaviorConfiguration="mybehavior">   
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="myhttpbind" contract="WcfCertificate.IService1">
          <identity>
            <dns value="TestServer" />
          </identity>
        </endpoint>
        <endpoint address="MEX" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    
    </services>
    
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        若要在調試過程中浏覽 Web 應用程式根目錄,請将下面的值設定為 True。
        在部署之前将該值設定為 False 可避免洩露 Web 應用程式檔案夾資訊。
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>
           

三:增加一個自定義驗證類

    它要繼承System.IdentityModel.Selector.UserNamePasswordValidator基類

public class Validator : UserNamePasswordValidator   
   {  
          
       public override void Validate(string userName, string password)  
       {  
           if (!string.Equals(userName, "sa") || !string.Equals(password, "1234"))  
               throw new Exception("Access Denied");  
       }   
   } 
           

四:建立siverlight客服端調用

       配置檔案,添加引用即可會自動生成

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647"
                    maxReceivedMessageSize="2147483647">
                    <security mode="TransportWithMessageCredential" />
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://localhost/Service1.svc" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
                name="BasicHttpBinding_IService1" />
        </client>
    </system.serviceModel>
</configuration>
           

  調用

   要注意使用者名密碼與伺服器要對應不然就會出現notfind

private void Hello_Click(object sender, RoutedEventArgs e)
        {
            ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
            sc.GetDataCompleted += sc_GetDataCompleted;

            //注意隻要這裡使用者名密碼錯誤,就會傳回notfind
            sc.ClientCredentials.UserName.UserName = "sa";
            sc.ClientCredentials.UserName.Password = "1234";
            MessageBox.Show("hello successful");
            sc.GetDataAsync(22);
        }
           

注意:

       1:跨域的問題

            需要在承載服務的域的根目錄中放置一個 clientaccesspolicy.xml 檔案     

<?xml version="1.0" encoding="utf-8" ?>  
<access-policy>  
  <cross-domain-access>  
    <policy>  
      <allow-from http-request-headers="*">  
        <domain uri="http://*"/>  
      </allow-from>  
      <grant-to>  
        <resource path="/" include-subpaths="true"/>  
      </grant-to>  
    </policy>  
  </cross-domain-access>  
</access-policy>
           

            跨域安全問題 http://hi.baidu.com/yandavid/item/06160508d060a218eafe3806

           這裡要注意的是加入了<domain uri="http:/">元素放入<allow-from>元素

               thank for http://blog.csdn.net/samon1688/article/details/4503842

wcf

繼續閱讀