2009-06-15 62 views
3

我需要調用在Windows域中運行的Web服務,該域與運行(Windows窗體)客戶端的Windows服務器不同。Web服務使用Windows身份驗證進行安全保護。如何使用存儲的憑據調用Web服務?

Web服務域的域憑證保存在客戶端的用戶配置文件(保存的用戶名和密碼在XP中),但我一直無法弄清楚如何在調用Web服務時使用這些保存的憑證。我發現很多的例子使用

WebService1.Credentials = System.Net.CredentialCache.DefaultCredentials 

(這不起作用,因爲它是本地域的憑據)

WebService1.Credentials = new NetworkCredentials(username, pwd, domain) 

(分別爲用戶名,密碼,域是硬編碼的)。

我使用CredEnumerateCredRead使用Windows API讀了,但不知道如何(或者如果)我可以一個PCREDENTIAL轉換爲管理NetworkCredentialReadCred不會爲存儲域憑據返回密碼)

有沒有人在這裏知道如何做到這一點?

謝謝!

回答

1

OK,我找到了解決辦法,所以我會回答我的問題:

首先,我發現,通過使用新的WCF式代理類「服務引用」允許您設置安全app.config文件中的設置。關鍵的(在我的情況)是隻設置運輸憑證的方式,指定Windows作爲類型,並確定該領域屬性域:

<system.serviceModel> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="Service1Soap" closeTimeout="00:01:00" openTimeout="00:01:00" 
        receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" 
        bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
        messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
        useDefaultWebProxy="true"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <security mode="TransportCredentialOnly"> 
         <transport clientCredentialType="Windows" realm="mydomain.com" /> 
        </security> 
       </binding> 
      </basicHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="http://server.mydomain.com/HelloWorldSvc/Service1.asmx" 
       binding="basicHttpBinding" bindingConfiguration="Service1Soap" 
       contract="ServiceReference1.Service1Soap" name="Service1Soap" /> 
     </client> 
    </system.serviceModel> 

接下來我用Hernan de Lahitte's優秀wrapperCredUIPromptForCredentials API函數以提示用戶輸入他們的憑據,如果安全異常,並將其存儲在他們的個人資料:

ServiceReference1.Service1SoapClient c = new Service1SoapClient(); 
retry: 
try 
{ 
    MessageBox.Show(this, c.HelloWorld()); 
} 
catch (System.ServiceModel.Security.MessageSecurityException securityException) 
{ 
    UserCredentialsDialog creds = new UserCredentialsDialog("*.mydomain.com", "My App", 
                     "Enter your enterprise credentials. Enter your user name as \"MyDomain\\username\""); 
    creds.Flags = UserCredentialsDialogFlags.Persist; 
    if (creds.ShowDialog() == DialogResult.OK) 
    { 
     goto retry; 
    } 
} 

c.Close(); 

是的,這是一個「GOTO」。 **** GASP **** :)

1

我不相信你可以直接使用它們。我相信你必須提示用戶,然後一旦用戶提供了他們,你可以再次提示。 Here is an article on how to do that。畢竟,如果你只能從DPAPI獲取憑證,那就會失敗。 :)

這是一些信息。以防萬一......

在DPAPI中保存數據的管理器稱爲Key Manager。您可以從UI做一個開始 - >運行訪問密鑰管理器...

rundll32.exe keymgr.dll, KRShowKeyMgr 

一般情況下,對於該認證功能都在發生的API是ADVAPI32。你可能能夠找到內容來幫助你。這是該API上的decent article

將您的憑據添加到CredentialCache時,您也可以嘗試authType "Negotiate"作爲described here

對不起,這只是一個研究轉儲 - 我沒有找到答案,但希望其中的一些可能會幫助你。 GL。

0

我不認爲你可以在代碼中使用它們,據我所知你唯一的選擇是:

  1. 硬編碼(一大禁忌在大多數情況下),你所寫的用戶名/密碼。
  2. 在域和計算機之間設置Kerberos with Trust,以便用戶域帳戶可以調用該服務。