【问题标题】:Authentication in WCF serviceWCF 服务中的身份验证
【发布时间】:2010-11-24 06:30:58
【问题描述】:

我在另一台机器上部署了 WCF 服务,我想根据 WCF 服务对客户端进行身份验证。

我做了以下事情:

1) 在 IIS 中,我取消选中匿名访问并选中“集成 Windows 身份验证”复选框。

2) 我的网络配置

 <authentication mode="Windows" />
 <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBind">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

3) 在客户端,我正在传递用户凭据,如下所示:

MyServiceClient _client;

_client = new MyServiceClient();

_client.ClientCredentials.Windows.ClientCredential.UserName = "username";
_client.ClientCredentials.Windows.ClientCredential.Password = "password";
_client.ClientCredentials.Windows.ClientCredential.Domain = "mydomain";

我的问题是如何在服务器端(部署服务的地方)捕获用户名和密码?

如何根据传递的凭据对用户进行身份验证?

目前我正在使用 basichttp 绑定.. 这个绑定是否足以支持安全模型?

【问题讨论】:

    标签: wcf wcf-security wcf-client


    【解决方案1】:

    在服务器端,您可以使用传入的 Windows 凭据对 Active Directory 进行身份验证,或者您需要使用备用存储来处理用户身份验证。

    您可以使用以下方法在服务器端代码中访问调用者的身份:

    IIdentity caller = ServiceSecurityContext.Current.PrimaryIdentity;
    

    您还可以通过检查

    ServiceSecurityContext.Current.WindowsIdentity
    

    如果它为 NULL,则没有传递任何 Windows 凭据 - 否则您可以使用此 Windows 身份来检查呼叫者(姓名等) - 但是,您将无法读取用户的密码!您可以查看他的姓名、他所属的群组等等。

    要使用 Windows/Active Directory 验证,请将 clientCredentialType 设置为“Windows”。您可能必须切换到 wsHttpBinding,甚至更好:netTcpBinding(如果您在防火墙后面的 Windows LAN 上)。

    <bindings>
      <netTcpBinding>
        <binding name="WindowsSecured">
          <security mode="Transport">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    

    这样,只有在您的 Windows 域中注册的用户才能调用该服务。如果您没有任何额外的工作,任何其他用户都将被拒绝。

    一旦您有 Windows 用户呼叫,您可以查看 ServiceSecurityContext.Current.WindowsIdentity 以了解有关谁呼叫的信息。

    查看MSDN docs 了解有关服务安全上下文中可用内容的详细信息,或查看Windows identity

    马克

    【讨论】:

    • 嗨,马克,感谢您的回复。我想要要求用户在 Windows 域中拥有帐户的安全模型。
    • 当前示例需要使用 SQL Server 数据库来存储用户信息,但我不希望这样,我想根据活动目录验证用户.. 如果它存在于当前域中或不存在。如果用户存在,那么在哪些组中......等
    • 再次感谢 marc,如果此代码适用于我的场景,我想再澄清一件事。实际上,我的“wcf 服务”部署在世界各地的多台机器上,所有机器都在同一个域中。这段代码是否可以在那种情况下工作。 Acutally 我必须验证用户是否属于同一个域。此外,当我使用 net tcp 绑定时,添加服务引用时出现以下错误。找不到与具有绑定 NetTcpBinding 的终结点的方案 net.tcp 匹配的基地址。注册的基地址方案是 [http]。
    • 另外,当我使用 wsHttpBinding 时,我收到以下错误:未提供服务证书。在 ServiceCredentials 中指定服务证书。
    • 对于 netTCP:您必须在服务的 &lt;host&gt; 部分中向“baseAddresses”添加一个条目:&lt;add baseAddress="net.tcp://YourServer:7575/YourServiceName" /&gt;,或者您需要使用“net.tcp”指定完整地址服务端点中的前缀。
    【解决方案2】:

    您似乎需要一个自定义用户名和密码验证器。有一篇 MSDN 文章涵盖了所有步骤:How to: Use a Custom User Name and Password Validator

    BasicHttpBinding 支持多种安全模式。如果您使用重载的构造函数,您可以为BasicHttpSecurityMode 传递您选择的值。

    【讨论】:

    • 感谢您的回复。实际上,我必须对用户进行身份验证,无论它是否存在于域中。例如,我的域是“abcd”我的用户是“user1”我必须在服务中识别可以捕获 user1 的位置并检查是否它是否存在于域中..
    • 好吧,如果你使用的是直接的 Windows 身份验证,那么上面的 marc_s 的答案就是要走的路。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多