在WCF服务中使用NetworkCredential

时间:2015-09-02 07:03:09

标签: c# asp.net .net wcf

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

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

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

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

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

我的问题是

  1. 为什么ClientCredentials在WCF中只读?
  2. 网络凭据如何运作?他们会在客户端或服务器端验证Windows登录吗?
  3. 我是否有办法在WCF中实现上述目的而不进行假冒?

2 个答案:

答案 0 :(得分:2)

我做过类似的事情 - 希望有所帮助:

 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>

答案 1 :(得分:1)

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

以下代码取自我的一个MVC projects, hence it has some ModelState`验证码,我相信您可以根据自己的需要对其进行修改。

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;
}