2010-09-01 187 views
8

我有一个简单的服务,我尝试设置身份验证。在客户端上,我希望用户输入他们的Windows用户帐户。 WCF将使用客户端提供的用户名/密码并对Windows身份验证进行身份验证。WCF安全认证

这里是我的服务器的app.config

<system.serviceModel> 
    <services> 
     <service name="WcfService.Service1" behaviorConfiguration="WcfService.Service1Behavior"> 
     <host> 
      <baseAddresses> 
      <add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfService/Service1/" /> 
      </baseAddresses> 
     </host> 
     <endpoint address ="" binding="wsHttpBinding" contract="WcfService.IService1"> 
      <identity> 
      <dns value="localhost"/> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="WcfService.Service1Behavior"> 
      <serviceMetadata httpGetEnabled="True"/> 
      <serviceDebug includeExceptionDetailInFaults="True" /> 

      <serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode = "Windows"/> 
      </serviceCredentials> 

     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

这里是我的客户的app.config

<system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
      <binding name="WSHttpBinding_IService1"> 

       <security mode = "Message"> 
       <message clientCredentialType = "UserName"/> 
       </security> 

      </binding> 
     </wsHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://localhost:8731/Design_Time_Addresses/WcfService/Service1/" 
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" 
      contract="ServiceReference1.IService1" name="WSHttpBinding_IService1"> 
      <identity> 
       <dns value="localhost" /> 
      </identity> 
     </endpoint> 
    </client> 
</system.serviceModel> 

这里是我的客户

ServiceReference1.Service1Client client = new WcfAuthentication.ServiceReference1.Service1Client(); 

client.ClientCredentials.UserName.UserName = "mywindowsusername"; 
client.ClientCredentials.UserName.Password = "mywindowsuserpassword"; 
Console.WriteLine(client.GetData(5)); 

但我对代码总是得到这个例外:

{“由于与远程端点的安全协商失败,无法打开安全通道。这可能是由于EndpointAddress中用于创建频道的EndpointIdentity缺失或不正确。请验证由EndpointAddress指定或暗示的EndpointIdentity正确标识远程端点。 “} {”安全令牌请求无效或格式错误元素“}

回答

7

它看起来像你产生服务和客户端配置分开(通过手工),通常使用svcutil或Visual Studio的“添加服务引用”从服务中生成客户端配置是一个好主意,这样您就知道您获得了与该服务相对应的客户端配置服务配置。

您想要什么是可能的,但WCF不允许您在使用wsHttpBinding时以明文形式传输用户名/密码令牌。这意味着您必须使用https托管您的服务或使用服务证书。 Here的帖子提供了更多的细节。

但我也想知道为什么你会想要这样的事情。使用集成的Windows身份验证可能是一个更好的主意。这甚至是wsHttpBinding的默认设置。这样你就不需要你的客户端输入他们的Windows用户名/密码。

+1

有趣的是,它非常有意义,它必须使用安全的连接。这只是了解wcf提供的不同认证可能性的练习。在现实世界。它适用于我的移动应用程序,用户需要在其移动设备上提供Windows帐户凭据。所以它使用basichttpbinding并保证我将要使用SSL(https)进行的通信。因此,例如上面使用nettcpbinding应该是正确的,因为我认为默认情况下它使用Transport应用程序已经用tcp加密。 – pdiddy 2010-09-01 19:59:36

-2
binding.Security = new WSHttpSecurity{Mode = SecurityMode.None};