C# WCF身份验证NT质询响应

C# WCF身份验证NT质询响应,c#,wcf,wcf-binding,wcf-security,wcf-client,C#,Wcf,Wcf Binding,Wcf Security,Wcf Client,当基本和/或windows身份验证打开且匿名身份验证关闭时,如何使我的控制台应用程序连接到IIS托管的WCF服务 该网站是内部的,不需要严格的安全措施。没有域控制器。但是,我需要关闭匿名访问 我已经搜索了几天,并尝试了许多方法,包括使用自托管证书和覆盖证书验证、覆盖UserNameValidator和使用client.ClientCredentials.Windows.ClientCredentials.UserName或client.ClientCredentials.UserName。这些都

当基本和/或windows身份验证打开且匿名身份验证关闭时,如何使我的控制台应用程序连接到IIS托管的WCF服务

该网站是内部的,不需要严格的安全措施。没有域控制器。但是,我需要关闭匿名访问

我已经搜索了几天,并尝试了许多方法,包括使用自托管证书和覆盖证书验证、覆盖
UserNameValidator
和使用
client.ClientCredentials.Windows.ClientCredentials.UserName
client.ClientCredentials.UserName
。这些都不起作用

如果有人愿意查看并运行代码,并帮助我使用身份验证运行示例,我会非常高兴

我已经上传了一个沙盒解决方案,其中包含HostWebSite、ClientConsole和API项目

我已在Windows Live SkyDrive上托管了zip文件:

一些小的设置步骤

  • 我添加到主机文件
    127.0.0.1 hostwebsite.local

  • 我在IIS中添加了一个网站
    --位置:
    主机网站项目根目录

    --绑定:
    hostwebsite.local

    --应用程序池:
    Classic 4.0应用程序池

  • 应用安全性
    Everyone
    读取主机网站项目目录的访问权限

  • 验证是否可以查看服务
    http://hostwebsite.local/services/EchoService.svc

  • 验证控制台是否回显hello world

  • 然后关闭匿名通过IIS/身份验证,并打开基本和/或windows身份验证

  • 谢谢

    为了方便读者,我在这里加入了代码片段
    项目:API

    namespace API.Contract
    {
        [ServiceContract]
        public interface IEcho
        {
            [OperationContract]
            string SendEcho(string message);
        }
    }
    namespace API.Proxy
    {
        public class EchoProxy : IEcho
        {
            public string SendEcho(string message)
            {
                return string.Concat("You said: ", message);
            }
        }
    }
    namespace API.Service
    {
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
        public class EchoService : System.ServiceModel.ClientBase<IEcho>, IEcho
        {
    
            public EchoService()
            {
            }
    
            public EchoService(string endpointConfigurationName) :
                base(endpointConfigurationName)
            {
            }
    
            public EchoService(string endpointConfigurationName, string remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
            {
            }
    
            public EchoService(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
            {
            }
    
            public EchoService(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
                base(binding, remoteAddress)
            {
            }
    
            public string SendEcho(string message)
            {
                return base.Channel.SendEcho(message);
            }
        }
    }
    
    客户端配置

    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IEcho" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
                    transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://hostwebsite.local/Services/EchoService.svc/services/EchoService.svc"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IEcho"
                contract="API.Contract.IEcho" name="WSHttpBinding_IEcho">
                <identity>
                    <servicePrincipalName value="host/mikev-ws" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
    
    
    
    项目:主机网站

    <system.serviceModel>
        <!-- SERVER -->
        <behaviors>
            <serviceBehaviors>
                <behavior name="MyServiceTypeBehaviors">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service name="API.Proxy.EchoProxy" behaviorConfiguration="MyServiceTypeBehaviors">
                <endpoint address="/services/EchoService.svc" binding="wsHttpBinding" contract="API.Contract.IEcho" />
                <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
            </service>
        </services>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    
    </system.serviceModel>
    

    您真的在关注消息级安全性吗?根据您的描述,您似乎需要传输级别的安全性(来自IIS)。为此,您必须获得正确的客户端配置文件。比如说,

    <binding ...
       ...
       <security mode="TransportCredentialOnly">
           <transport clientCredentialType="windows" proxyCredentialType="None" realm="" />
    ...
    
    <binding ...
           ...
           <security mode="TransportCredentialOnly">
               <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
    
    <system.serviceModel>
        <!-- SERVER -->
        <bindings>
            <basicHttpBinding>
                <binding name="NewBinding">
                    <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Basic" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        ...
        <services>
            <service name="API.Proxy.EchoProxy" ...
               <endpoint binding="basicHttpBinding" bindingConfiguration="NewBinding" contract="API.Contract.IEcho" />
          ...
    
    编辑

    为了使用http协议进行基本身份验证,您必须在服务器端和服务器端进行配置。比如说,

    <binding ...
       ...
       <security mode="TransportCredentialOnly">
           <transport clientCredentialType="windows" proxyCredentialType="None" realm="" />
    ...
    
    <binding ...
           ...
           <security mode="TransportCredentialOnly">
               <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
    
    <system.serviceModel>
        <!-- SERVER -->
        <bindings>
            <basicHttpBinding>
                <binding name="NewBinding">
                    <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Basic" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        ...
        <services>
            <service name="API.Proxy.EchoProxy" ...
               <endpoint binding="basicHttpBinding" bindingConfiguration="NewBinding" contract="API.Contract.IEcho" />
          ...
    
    
    ...
    
    @维奈克:你好,谢谢你的帮助。你的两个建议我都试过了。我不得不将绑定更改为basicHttpBinding;对吗?我收到的第一次配置更改的错误消息是
    HTTP请求未经客户端身份验证方案“协商”授权。从服务器接收到的身份验证标头为“Basic realm=“hostwebsite.local”。
    。第二条错误消息(其中有配置更改和身份验证代码)与我提到的第一条错误消息相同,只是“协商”一词被替换为Ntlm。感谢you@Valamas,要使第一次配置更改生效,您必须在IIS上允许集成/windows身份验证。在这里,登录到客户端计算机的用户的凭据将提供给服务器-如果服务器上无法识别此用户,则此操作将不起作用。要使用基本身份验证方案,您需要将clientCredentialType更改为basic,设置域值,在代码中,您必须设置ClientCredentials.UserName(设置用户和密码)。@VinayC:我正在遵循基本身份验证路径。IIS中仅启用基本身份验证。我遵循了你的上一个声明,包括我设置为空的领域。在IIS中,在基本身份验证下,领域和域字段也为空。浏览服务页面返回错误(
    http://hostwebsite.local/Services/EchoService.svc
    ):
    此服务的安全设置需要“匿名”身份验证,但未为承载此服务的IIS应用程序启用此身份验证。
    。。。。(续)如果您希望看到当前配置和代码更改@Valamas,Appologys-通常,基本身份验证应该与https一起使用。因此,要使用http,我相信您需要配置服务器端绑定,并且,我已经编辑了答案以显示该部分。