【问题标题】:Using NetworkCredential in WCF services在 WCF 服务中使用 NetworkCredential
【发布时间】:2015-09-02 07:03:08
【问题描述】:

我有一个 WCF 服务,它使用 Windows 身份验证来查看服务合同,并且服务中的特定方法被配置为只能由特定用户 UserX 访问。

[PrincipalPermission(SecurityAction.Demand,Name="xxx\\UserA")]

在客户端,我需要访问上面的服务方法。如果我使用的是网络参考 -> 我添加以下内容

client = new WebRefLocal.Service1();
client.Credentials = new System.Net.NetworkCredential("UserA", "xxxxxx", "test");

但在 WCF 服务参考中无法实现上述操作,因为客户端凭据是只读的。我可以实现上述目标的一种最佳方法是模仿 https://msdn.microsoft.com/en-us/library/ff649252.aspx

我的问题是

  1. 为什么在 WCF 中将 ClientCredentials 设为只读?
  2. 网络凭据如何工作?他们会在客户端或服务器端验证 Windows 登录吗?
  3. 有没有什么方法可以在 WCF 中实现上述目标而无需模拟?

【问题讨论】:

  • 查看基于声明的身份验证
  • @MickyDuncan 一直在使用 WCF 进行模拟,一旦遇到双跳问题,它就会变得非常棘手。使用基于索赔的系统可以减轻痛苦
  • How to specify Windows credentials in WCF client configuration file 的可能副本。虽然指的是“配置文件”,但解决方案是基于代码的
  • @3dd Ahh 你指的是第 3 点。是的,完全同意你的看法,好伙伴!从我的 DCOM 时代开始,我仍在接受治疗
  • 即使基于代码在 WCF 下也是不可能的,因为 ClientCredentials 是只读的,我们不能为服务客户端分配任何新的凭据。这就是为什么我正在研究模拟但觉得处理起来太复杂了。

标签: c# asp.net .net wcf


【解决方案1】:

我做过这样的事情 - 希望它有所帮助:

 var credentials = new ClientCredentials();
credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Delegation;
credentials.Windows.ClientCredential = new System.Net.NetworkCredential("UserA", "xxxxxx", "test");

client.Endpoint.Behaviors.Remove<ClientCredentials>();
client.Endpoint.Behaviors.Add(credentials);

与具有以下安全设置的BasicHttpBinding 一起使用:

  <security mode="TransportCredentialOnly">
    <transport clientCredentialType="Windows" proxyCredentialType="Windows" />
  </security>

【讨论】:

  • 你能分享一下你在上面使用的绑定是什么吗??
  • 谢谢.. 这给了我确切的解决方案.. 我做了以下 service.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("xxx", "yyyy", "zzzz") ; ServRef.Resultresult = service.GetData();我也没有使用模拟..:)
【解决方案2】:

您可以使用的一种方法是在调用 WCF 服务时使用ChannelFactory

以下代码取自我的 MVCprojects, hence it has someModelState` 验证代码之一,我相信您可以修改它以满足您的需求。

protected R ExecuteServiceMethod<I, R>(Func<I, R> serviceCall) {
    R result = default(R);
    ChannelFactory<I> factory = CreateChannelFactory<I>();
    try {
        I manager = factory.CreateChannel();
        result = serviceCall.Invoke(manager);
    } catch (FaultException<ValidationFaultException> faultException) {
        faultException.Detail.ValidationErrors.ToList().ForEach(e => ModelState.AddModelError("", e));
    } finally {
        if (factory.State != CommunicationState.Faulted) factory.Close();
    }
    return result;
}

private ChannelFactory<I> CreateChannelFactory<I>() {
   UserAuthentication user = GetCurrentUserAuthentication();

   ChannelFactory<I> factory = new ChannelFactory<I>("Manager");

   if (IsAuthenticated) {
       factory.Credentials.UserName.UserName = user.UserName;
       factory.Credentials.UserName.Password = user.Password;
   }

   BindingElementCollection elements = factory.Endpoint.Binding.CreateBindingElements();
   factory.Endpoint.Binding = new CustomBinding(elements);
   SetDataContractSerializerBehavior(factory.Endpoint.Contract);

   return factory;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多