WCF安全认证

8

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

这是我的服务器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是否正确标识了远程端点。"} {"安全令牌请求具有无效或格式不正确的元素。"}

3个回答

7
看起来你是手动分别生成了服务和客户端配置。通常最好使用svcutil或Visual Studio的“添加服务引用”从服务端生成客户端配置。这样你就知道你得到了与服务配置相对应的客户端配置。
你想要的是可能的,但在使用wsHttpBinding时,WCF不允许你以纯文本形式传输用户名/密码令牌。这意味着你必须使用https来托管你的服务,或使用服务证书。这里有一篇帖子详细介绍了这个问题。
但我也想知道为什么你要这样做。更好的做法可能是使用集成Windows身份验证。这甚至是wsHttpBinding的默认设置。这样你就不需要让客户端输入他们的Windows用户名/密码了。

1
有趣的是,使用安全连接是完全有道理的。这只是一个练习,以了解wcf提供的不同身份验证可能性。在现实世界中,这是为我的移动应用程序而设计的,用户需要在其移动设备上提供Windows帐户凭据。因此,它使用basichttpbinding,并且为了保护通信,我将选择SSL(https)。因此,例如上面使用nettcpbinding应该是正确的,因为我认为默认情况下它使用传输安全性,应该已经使用tcp进行加密。 - pdiddy

2

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接