2009-06-15 71 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,以便用户域帐户可以调用该服务。