1. 程式人生 > >WCF基於使用者名稱和密碼安全成功測試

WCF基於使用者名稱和密碼安全成功測試

經過多次測試,終於探出一種很合適我使用的WCF安全驗證模式。 
  
目標: 
1.客戶端與伺服器端通訊使用x509證書驗證,但不用客戶端安裝證書。只需要伺服器端配置好證書即可。 
2.驗證使用使用者名稱密碼形式。 
  
操作: 
(這裡的測試使用wcf專案模板預設的服務,即只要新建一個使用vs2008自動生成的wcf專案就行了,

它會自動生成有一個GetData方法,我就用這個方法進行測試) 
  
1.新建WCF服務應用程式.

1.1生成一個伺服器證書:執行Visual Studio 2008 命令提示工具:

輸入:makecert -r -pe -n "CN=MyServer" -sr LocalMachine -ss My -sky exchange執行。

-sr LocalMachine 請一定儲存到LodcalMachine中.目的就是到時如果你部署這個wcf服務的時候可以讓IIS找到證書,

反之,IIS會報找不到x509證書.


2.配置web.config檔案: 
這裡要注意的是把storeLocation設為LocalMachine,原因也是到時需要部署的時候可以免掉很多麻煩,因為以後釋出到iis時很可以不能正常驗證到證書的私鑰.

  1. <system.serviceModel>
  2. <bindings>
  3. <wsHttpBinding>
  4. <bindingname="NewBinding0">
  5. <
    security>
  6. <messageclientCredentialType="UserName"/>
  7. </security>
  8. </binding>
  9. </wsHttpBinding>
  10. </bindings>
  11. <services>
  12. <servicebehaviorConfiguration="WcfService2.Service1Behavior"
  13. name="WcfService2.Service1">
  14. <endpointaddress=""binding="wsHttpBinding"bindingConfiguration
    ="NewBinding0"
  15. contract="WcfService2.IService1">
  16. </endpoint>
  17. <endpointaddress="mex"binding="mexHttpBinding"contract="IMetadataExchange"/>
  18. </service>
  19. </services>
  20. <behaviors>
  21. <serviceBehaviors>
  22. <behaviorname="WcfService2.Service1Behavior">
  23. <serviceMetadatahttpGetEnabled="true"/>
  24. <serviceDebugincludeExceptionDetailInFaults="false"/>
  25. <serviceCredentials>
  26. <clientCertificate>
  27. <authenticationcertificateValidationMode="None"/>
  28. </clientCertificate>
  29. <serviceCertificatefindValue="MyServer"storeLocation="LocalMachine"x509FindType="FindBySubjectName"/>
  30. <userNameAuthenticationuserNamePasswordValidationMode="Custom"
  31. customUserNamePasswordValidatorType="WcfService2.MyUserNamePasswordValidator,WcfService2"/>
  32. </serviceCredentials>
  33. </behavior>
  34. </serviceBehaviors>
  35. </behaviors>
  36. </system.serviceModel>

3.建造驗證客戶端使用者名稱和密碼的方法.

這裡注意的是必須與web.config檔案中的customUserNamePasswordValidatorType=中的內容一致,

格式是:"名稱空間.方法名,名稱空間"

實際專案應用中這裡應該是從資料庫裡確認用客是否合法。

  1. namespace WcfService2
  2. {
  3. publicclass MyUserNamePasswordValidator : UserNamePasswordValidator
  4.     {
  5. publicoverridevoid Validate(string userName, string password)
  6.         {
  7. if (userName != "jac" || password != "jac")
  8.             {
  9. thrownew SecurityTokenException("Unknown Username or Password");
  10.             }
  11.         }
  12.     }
  13. }

至此,wcf服務配置完成。

4.新建一個asp.net專案,並新增服務引用這個wcf服務.

5.修改asp.net專案的web.config檔案(一定要在引用wcf服務後).

新增一個endpointBehaviors,

  1. <behaviors>
  2. <endpointBehaviors>
  3. <behaviorname="jacBehavior">
  4. <clientCredentials>
  5. <serviceCertificate>
  6. <authenticationcertificateValidationMode="None"/>
  7. </serviceCertificate>
  8. </clientCredentials>
  9. </behavior>
  10. </endpointBehaviors>
  11. </behaviors>

然後讓它生效,

  1. <endpointaddress="http://j-8de9be98d1184/Service1.svc"behaviorConfiguration="jacBehavior"
  2. binding="wsHttpBinding"bindingConfiguration="WSHttpBinding_IService1"
  3. contract="ServiceReference1.IService1"name="WSHttpBinding_IService1">

發下是完整的asp.net客戶端的web.config檔案的system.serviceModel部份

  1. <system.serviceModel>
  2. <behaviors>
  3. <endpointBehaviors>
  4. <behaviorname="jacBehavior">
  5. <clientCredentials>
  6. <serviceCertificate>
  7. <authenticationcertificateValidationMode="None"/>
  8. </serviceCertificate>
  9. </clientCredentials>
  10. </behavior>
  11. </endpointBehaviors>
  12. </behaviors>
  13. <bindings>
  14. <wsHttpBinding>
  15. <bindingname="WSHttpBinding_IService1"closeTimeout="00:01:00"
  16. openTimeout="00:01:00"receiveTimeout="00:10:00"sendTimeout="00:01:00"
  17. bypassProxyOnLocal="false"transactionFlow="false"hostNameComparisonMode="StrongWildcard"
  18. maxBufferPoolSize="524288"maxReceivedMessageSize="65536"messageEncoding="Text"
  19. textEncoding="utf-8"useDefaultWebProxy="true"allowCookies="false">
  20. <readerQuotasmaxDepth="32"maxStringContentLength="8192"maxArrayLength="16384"
  21. maxBytesPerRead="4096"maxNameTableCharCount="16384"/>
  22. <reliableSessionordered="true"inactivityTimeout="00:10:00"
  23. enabled="false"/>
  24. <securitymode="Message">
  25. <transportclientCredentialType="Windows"proxyCredentialType="None"
  26. realm=""/>
  27. <messageclientCredentialType="UserName"negotiateServiceCredential="true"
  28. algorithmSuite="Default"establishSecurityContext="true"/>
  29. </security>
  30. </binding>
  31. </wsHttpBinding>
  32. </bindings>
  33. <client>
  34. <endpointaddress="http://j-8de9be98d1184/Service1.svc"behaviorConfiguration="jacBehavior"
  35. binding="wsHttpBinding"bindingConfiguration="WSHttpBinding_IService1"
  36. contract="ServiceReference1.IService1"name="WSHttpBinding_IService1">
  37. <identity>
  38. <certificateencodedValue="AwAAAAEA.....................eGtnWJsvtFQsEuzDYw=="/>
  39. </identity>
  40. </endpoint>
  41. </client>
  42. </system.serviceModel>

6.呼叫.

  1.             ServiceReference1.Service1Client sc = new WebApplication1.ServiceReference1.Service1Client();
  2.             sc.ClientCredentials.UserName.UserName = "jac";
  3.             sc.ClientCredentials.UserName.Password = "jac";
  4.             Label1.Text = sc.GetData(22);

完成。

原始檔請到我的資源中下載.

還想提下,這個csdn部落格的寫部落格的TextEditer爛到極點了。。