WCF TCP Windows身份验证问题

时间:2014-06-26 10:30:52

标签: c# windows wcf authentication tcp

我的情况是我有2台机器。

  • 机器A
  • 机器B

计算机B上的客户端成功连接到计算机A上的主机。

计算机B上的客户端成功连接到计算机B上的主机。

计算机A上的客户端成功连接到计算机B上的主机。

计算机A上的客户端无法连接到计算机A上的主机。 - System.ServiceModel.Security.SecurityNegotiationException:服务器已拒绝客户端凭据。

我正在使用Windows身份验证。

客户端:

        var netTcpBinding = new NetTcpBinding()
        {
            Security = new NetTcpSecurity()
            {
                Mode = SecurityMode.Transport,
                Transport = new TcpTransportSecurity()
                {
                    ClientCredentialType = TcpClientCredentialType.Windows,
                }
            },
            TransferMode = TransferMode.Streamed,
            MaxReceivedMessageSize = long.MaxValue,
            MaxBufferSize = int.MaxValue,
            MaxBufferPoolSize = long.MaxValue,
            ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
            {
                MaxDepth = int.MaxValue,
                MaxArrayLength = int.MaxValue,
                MaxStringContentLength = int.MaxValue
            },
            SendTimeout = TimeSpan.MaxValue,
            ReceiveTimeout = TimeSpan.MaxValue
        };

        string endpointAddress;
        if (port == 0)
            endpointAddress = string.Format("net.tcp://{0}/Configuration", host);
        else
            endpointAddress = string.Format("net.tcp://{0}:{1}/Configuration", host, port);

        Console.WriteLine("Endpoint: {0}", endpointAddress);

        var factory = new ChannelFactory<IMyChannel>(netTcpBinding);
        factory.Endpoint.Address = new EndpointAddress(new Uri(endpointAddress), new DnsEndpointIdentity("MyDns"));

        //Do not verify
        factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;

        factory.Credentials.Windows.ClientCredential.Domain = domain;
        factory.Credentials.Windows.ClientCredential.UserName = username;
        factory.Credentials.Windows.ClientCredential.Password = password;

        //Console.WriteLine("Opening Channel Factory ... ");
        factory.Open();

主机:

    #region INIT

    //Set configuration file just once
    if (ChannelServices.RegisteredChannels.Length == 0)
    {
        RemotingConfiguration.Configure(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, false);
    }

    _serviceHost = null;
    _serviceHost = new ServiceHost(typeof(MyChannel));
    _serviceHost.AddDefaultEndpoints();

    // build list with local IP addresses to bind to
    var localIpAddresses = new List<IPAddress>(Dns.GetHostAddresses(Dns.GetHostName()));
    if (IPAddress.Loopback != null)
        localIpAddresses.Add(IPAddress.Loopback);
    localIpAddresses.RemoveAll(i => i.AddressFamily != AddressFamily.InterNetwork);

    // enable metadata exchange bahaviour
    // add metadatabehaviour in case HTTP is not enabled
    var metadataBehaviour = _serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
    if (metadataBehaviour == null)
    {
        metadataBehaviour = new ServiceMetadataBehavior();
        _serviceHost.Description.Behaviors.Add(metadataBehaviour);
    }

    var credentialsBehaviour = _serviceHost.Description.Behaviors.Find<ServiceCredentials>();
    if (credentialsBehaviour == null)
    {
        credentialsBehaviour = new ServiceCredentials();
        _serviceHost.Description.Behaviors.Add(credentialsBehaviour);
    }

    var serviceDebug = _serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
    if (serviceDebug == null)
    {
        serviceDebug = new ServiceDebugBehavior();
        _serviceHost.Description.Behaviors.Add(serviceDebug);
    }
    serviceDebug.IncludeExceptionDetailInFaults = true;

    var tcpPort = "9096";

    _log.Info("tcpPort - {0}", tcpPort);

    var netTcpBinding = new NetTcpBinding()
    {
        Security = new NetTcpSecurity()
        {
            Mode = SecurityMode.Transport,
            Transport = new TcpTransportSecurity()
            {
                ClientCredentialType = TcpClientCredentialType.Windows,
            }
        },
        TransferMode = TransferMode.Streamed,
        MaxReceivedMessageSize = long.MaxValue,
        MaxBufferSize = int.MaxValue,
        MaxBufferPoolSize = long.MaxValue,
        ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
        {
            MaxDepth = int.MaxValue,
            MaxArrayLength = int.MaxValue,
            MaxStringContentLength = int.MaxValue
        },
        SendTimeout = TimeSpan.MaxValue,
        ReceiveTimeout = TimeSpan.MaxValue
    };

    var endpoint = _serviceHost.AddServiceEndpoint(
        typeof(IMyChannel),
        netTcpBinding,
        new Uri(string.Format("net.tcp://0:{0}/Configuration", tcpPort)));

    ServiceSecurityAuditBehavior newAudit = new ServiceSecurityAuditBehavior();
    newAudit.AuditLogLocation = AuditLogLocation.Application;
    newAudit.MessageAuthenticationAuditLevel = AuditLevel.SuccessOrFailure;
    newAudit.ServiceAuthorizationAuditLevel = AuditLevel.SuccessOrFailure;
    newAudit.SuppressAuditFailure = false;

    _serviceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
        MetadataExchangeBindings.CreateMexTcpBinding(),
        string.Format("net.tcp://localhost:{0}/Configuration/mex", tcpPort));

    _serviceHost.Description.Behaviors.Remove<ServiceSecurityAuditBehavior>();
    _serviceHost.Description.Behaviors.Add(newAudit);

    _serviceHost.Opening += (sender, eventArgs) => _log.Info("Opening Connection ...");
    _serviceHost.Opened += (sender, eventArgs) => _log.Info("Opened Connection ...");

    _serviceHost.Closing += (sender, eventArgs) => _log.Info("Closing connection ...");
    _serviceHost.Closed += (sender, eventArgs) => _log.Info("Closed connection ...");

    _serviceHost.Faulted += (sender, eventArgs) => _log.Error("Fault detected on WCF host");

    _serviceHost.Open();
    #endregion

这是我的完整堆栈跟踪:

  

System.ServiceModel.Security.SecurityNegotiationException:服务器   已拒绝客户端凭据。 ---&GT;   System.Security.Authentication.InvalidCredential异常:服务器   拒绝了客户凭据。 ---&GT; System.Component   Model.Win32Exception:登录尝试失败---内部结束   异常堆栈跟踪--- at   System.Net.Security.NegoState.ProcessReceivedBlob(Byte []消息,   LazyAsyn cResult lazyResult)at   System.Net.Security.NegoState.StartSendBlob(Byte []消息,   LazyAsyncResul t lazyResult)at   System.Net.Security.NegoState.CheckCompletionBeforeNextSend(字节[]   消息,LazyAsyncResult lazyResult)at   System.Net.Security.NegoState.ProcessReceivedBlob(Byte []消息,   LazyAsyn cResult lazyResult)at   System.Net.Security.NegoState.StartSendBlob(Byte []消息,   LazyAsyncResul t lazyResult)at   System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult   lazyRe sult)at   System.Net.Security.NegotiateStream.AuthenticateAsClient(的NetworkCredential   凭证,String targetName,ProtectionLevel   requiredProtectionLevel,TokenIm personationLevel   allowedImpersonationLevel)at   System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsS   treamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream,   SecurityMessagePr operty&amp; remoteSecurity)---内心的结束   异常堆栈跟踪---

     

服务器堆栈跟踪:at   System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsS   treamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream,   SecurityMessagePr operty&amp; remoteSecurity)at   System.ServiceModel.Channels.StreamSecurityUpgradeInitiatorBase.InitiateUp   等级(溪流)at   System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade(STREA   mUpgradeInitiator upgradeInitiator,IConnection&amp;连接,   ClientFramingDecode r decoder,IDefaultCommunicationTimeouts   defaultTimeouts,TimeoutHelper&amp;超时助手)   System.ServiceModel.Channels.StreamedFramingRequestChannel.SendPreamble(IC   onnection connection,TimeoutHelper&amp; timeoutHelper,   ClientFramingDecoder解码器,SecurityMessageProperty&amp;   remoteSecurity)at   System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedConnect   ionPoolHelper.AcceptPooledConnection(IConnection连接,   TimeoutHelper&安培;超时的时间   System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(时间   跨度超时)at   System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedFraming   Request.SendRequest(消息消息,TimeSpan超时)at   System.ServiceModel.Channels.RequestChannel.Request(消息消息,   TimeS pan timeout)at   System.ServiceModel.Channels.ServiceChannel.Call(String action,   eway上的布尔值,ProxyOperationRuntime操作,Object [] ins,   对象[]出局,TimeSpan时间表)   System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCall   消息methodCall,ProxyOperationRuntime操作)at   System.ServiceModel.Channels.ServiceChannelProxy.Invoke(即时聊天   消息)

     

在[0]处重新抛出异常:at   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(即时聊天   req Msg,IMessage retMsg)at   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&安培;   msgDa ta,Int32类型)在MyProject.TestConnection()处   d:\ Source \ MyProject \ Program.cs:行中的MyProject.Program.ManualInput()   84

没有任何意义。

任何帮助将不胜感激!

谢谢!

ķ

1 个答案:

答案 0 :(得分:0)

解决!

此问题是Windows身份验证不需要DnsEndpointIdentity:)