具有Windows身份验证的WCF服务不会拒绝不受信任的用户

时间:2019-07-08 14:53:46

标签: windows wcf authentication

我正在WPF应用程序和Windows服务抛出WCF之间开发一种“自动连接”模式。 我只想允许受信任的域用户连接到特定的WCF服务,而不需要Windows凭据(该用户已经在Windows会话中登录)。 接下来,该服务将使用户登录到应用程序。

我创建了一个WCF服务,其安全性模式设置为«Transport»,而Transport.ClientCredentialType设置为«Windows»(客户端和服务器上的绑定均相同)。 在同一应用程序中还运行着其他WCF服务,其安全模式设置为“无”。

当我在使用LocalService帐户的域计算机上运行Windows服务,并在使用域用户帐户的另一台计算机上运行客户端时,可以在OperationContext对象的服务器端获取用户Windows身份«DOMAIN \ user» 。 我看到使用了Kerberos,并且我认为可以进行某种形式的模拟,

但是,当我在不认识域用户的工作组计算机(域外)上运行Windows服务时,OperationContext WindowsIdentity设置为“ MACHINE_NAME \ Administrator”(在服务器上创建的本地会话)。 没有错误,服务请求也没有例外,我也不知道为什么。 WindowsIdentity对象的IsAuthenticated属性始终设置为true。

我已经在«消息»的安全模式下进行了测试。

我想知道是否有可能告诉WCF拒绝所有未经真正身份验证的连接吗?

更新: 这里的一些信息可能会有所帮助:

  • 客户端应用程序是WPF应用程序
  • 服务器是经典的Windows服务,在本地服务下运行
  • 绑定是net.tcp
  • 客户端代理类是通过svcutil.exe生成的
  • 一切都由代码完成,没有配置文件
  • 以下是创建ServiceClient的代码:
 public static TClient Create<TClient, TChannel>(params IContractBehavior[] behaviors)
          where TChannel : class
          where TClient : ClientBase<TChannel>
        {
            var typeOfClient = typeof(TClient);
            var ctor = typeOfClient.GetConstructor(new[] { _bindingType, _endpointAddressType });
            if (ctor == null)
            {
                throw new Exception($"{typeOfClient} has no constructor taking 2 parameters ({_bindingType},{_endpointAddressType})");
            }
            var address = getClientBaseEndPointAddress(typeof(TChannel));
            var binding = getBinding<TClient>(address.Uri.Scheme);
            var clt = (TClient)ctor.Invoke(new object[] { binding, address });
            foreach (var behavior in behaviors)
            {
                clt.ChannelFactory.Endpoint.Contract.Behaviors.Add(behavior);
            }
            manageDataContractResolver<TClient, TChannel>(clt);
            clt.setOperationTimeout(binding.SendTimeout);
            return clt;
        }
  • getBinding方法由客户端和服务器应用程序共享:
   var ret = new NetTcpBinding
   {
      MaxBufferSize = bc.MessageSize,
      MaxBufferPoolSize = bc.MessageSize,
      ...        
   };

   // Secured or not
   if (secured)
   {
      ret.Name = "Default_Secured_Binding";
      ret.Security.Mode = SecurityMode.Transport;
      ret.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;      
    }
    else
    {
       ret.Security.Mode = SecurityMode.None;
       ret.Name = "Default_Binding";
    }

我以为WCF会拒绝任何未经完全身份验证的请求,但我不会收到任何“身份验证错误”。

让我知道是否需要更多信息。

1 个答案:

答案 0 :(得分:0)

如果客户端未提供Windows凭据作为客户端Windows凭据,则将使用当前计算机用户的凭据进行身份验证。身份验证的条件是可以将此凭据登录到服务器(Windows用户)
客户端如何调用服务,客户端代理类或ChannelFactory?这是在客户端设置证书的方法。

ServiceReference2.Service1Client client = new ServiceReference2.Service1Client();
            //if we don't set up this, The computer user credentials that are currently running the program will be sent to the server.
            client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
            client.ClientCredentials.Windows.ClientCredential.Password = "123456";

假设服务器端配置在下面,

  <system.serviceModel>
    <services>
      <service name="WcfService1.Service1">
        <endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1" bindingConfiguration="mybinding">
        </endpoint>
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"></endpoint>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="mybinding">
          <security mode="Transport">
            <transport clientCredentialType="Windows"></transport>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

请张贴完整的服务器配置和客户端配置(system.servicecmodel部分)以供调用,我会尝试查找问题。
随时让我知道是否有什么可以帮助您的。