代码之家  ›  专栏  ›  技术社区  ›  blu

WCF和Kerberos身份验证

  •  9
  • blu  · 技术社区  · 15 年前

    安装程序

    • Windows 2003 R2上的IIS 6.0 R2-SP 2
    • 已添加计算机的SPN(http/myserver&http/我的服务器:8080)
    • 已为IIS应用程序池创建广告帐户

    我正在使用 Brian Booth's debug site

    我已经将这些设置镜像到承载WCF服务的站点。

    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WsHttpBindingConfig">
                    <security>
                        <message negotiateServiceCredential="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings> 
        <services>
            <service behaviorConfiguration="ServiceBehavior" name="Service">    
                <endpoint address="" 
                    binding="wsHttpBinding" 
                    bindingConfiguration="WsHttpBindingConfig" 
                    contract="IService">    
                    <identity>    
                        <servicePrincipalName value="http/myserver" />    
                        <dns value="" />    
                    </identity>    
                </endpoint>    
                <endpoint address="mex" 
                    binding="mexHttpBinding" 
                    contract="IMetadataExchange" />    
            </service>    
        </services>    
        <behaviors>    
            <serviceBehaviors>    
                <behavior name="ServiceBehavior">    
                    <serviceMetadata httpGetEnabled="true"/>    
                    <serviceDebug includeExceptionDetailInFaults="true"/>    
                    <serviceAuthorization 
                        impersonateCallerForAllOperations="true" />    
                </behavior>    
            </serviceBehaviors>    
        </behaviors>    
    </system.serviceModel>
    

    Web服务-Web方法

    [OperationBehavior(Impersonation = ImpersonationOption.Required)]
    public string GetCurrentUserName()
    {
        string name = WindowsIdentity.GetCurrent().Name;
        return name;
    }
    

    客户端应用程序-应用程序配置

    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IService" 
                    ... />
                    ...
                    <security mode="Message">
                        <transport clientCredentialType="Windows" 
                            proxyCredentialType="None" 
                            realm="" />
                        <message clientCredentialType="Windows" 
                            negotiateServiceCredential="true"
                            algorithmSuite="Default" 
                            establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://myserver/Service.svc" 
                binding="wsHttpBinding" 
                bindingConfiguration="WSHttpBinding_IService"
                contract="KerberosService.IService" 
                name="WSHttpBinding_IService">
                <identity>
                    <servicePrincipalName value="http/myserver" />
                </identity>
            </endpoint>
         </client>
    </system.serviceModel>
    

    应用程序错误

    客户端身份验证方案 “匿名”。身份验证标头 从服务器接收到 “谈判,NTLM。”

    事件日志中存在以下错误:

    例外情况: System.ServiceModel.ServiceActivationException: 服务'/服务.svc“不可能 由于在 is:此服务的安全设置 承载此服务的应用程序。

    我不明白。这项服务的重点是不允许匿名身份验证,每个用户/请求都必须使用Kerberos票证进行身份验证,然后将它们传递给其他计算机。

    修订版1

    阅读后 this SO question 我删除了元数据端点。这并没有解决问题。

    经过进一步的研究,我发现了一些建议将wsHttpBinding更改为basicHttpBinding的帖子。对该部分的修改web.config文件,并且服务端点已更新以引用该绑定。

    Web服务-Web配置(修订版)

    <basicHttpBinding>
        <binding name="basicBindingConfig">
            <security mode="TransportCredentialOnly">
                <transport clientCredentialType="Windows" 
                    proxyCredentialType="Windows" 
                    realm="" />
            </security>
        </binding>
    </basicHttpBinding>
    

    客户端应用程序-应用程序配置(修订版)

    <!-- ... -->
    <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" 
            proxyCredentialType="Windows"
            realm="" />
        <message clientCredentialType="UserName" 
            algorithmSuite="Default" />
    </security>
    <!-- ... -->
    

    客户端身份验证方案 “在这里谈些什么

    4 回复  |  直到 7 年前
        1
  •  7
  •   Sven Sönnichsen    15 年前

    对我来说,当前的设置是有效的:

    <system.serviceModel>
      <bindings>
        <wsHttpBinding>
          <binding name="wsHttpBindingConf" useDefaultWebProxy="true"/>
        </wsHttpBinding>
      </bindings>
    
      <services>
        <service behaviorConfiguration="returnFaults" name="Epze.BusinessLayer.ZeitManager">
            <endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpBindingConf" contract="Epze.Contract.IZeitManager"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
      </services>
    
      <behaviors>
        <serviceBehaviors>
            <behavior name="returnFaults">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <serviceAuthorization impersonateCallerForAllOperations="true"/>
            </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
    

    为WCF的所有方法设置以下属性:

    [OperationBehavior(Impersonation = ImpersonationOption.Required)]
    

    在客户机上:

    <system.serviceModel>
      <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IZeitManager" 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" establishSecurityContext="true"/>
                </security>
            </binding>
        </wsHttpBinding>
      </bindings>
    
      <behaviors>
        <endpointBehaviors>
            <behavior name="Delegation">
            <clientCredentials>
                <windows allowedImpersonationLevel="Delegation" />
            </clientCredentials>
            </behavior>
        </endpointBehaviors>
      </behaviors>        
    
      <client>
        <endpoint address="http://server.mydomain.net/ePZEsvc/ZeitManager.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IZeitManager" 
                  contract="External.Epze.IZeitManager" name="WSHttpBinding_IZeitManager" behaviorConfiguration="Delegation">
            <identity>
                <servicePrincipalName value="HOST/localhost"/>
            </identity>                      
        </endpoint>
      </client>
    </system.serviceModel>
    

    汉斯,斯文

        2
  •  3
  •   marc_s Anurag    15 年前

    在最初的部分中,您有 <security>..... 在web.config文件(省略了mode=“message”),以及 <security mode="Message"> 在客户端。

    <security mode="TransportCredentialOnly"> .

    问题真的是:你能保证在被调用的客户端和服务器之间只有一个网络分支吗?一、 这是在公司防火墙后面吗?在这种情况下,我建议使用netTcp绑定 <security mode="Transport">

    <security mode=“消息”> 并使用证书对服务进行身份验证(这样服务和客户机就有一个用于加密的公共“秘密”)。

    大卫萨克斯坦有一个 great series of blog posts 解释了行业大师JuvalLowy已经确定的五种安全场景(在他的 Programming WCF

    马克

        3
  •  2
  •   Jonathan    13 年前

    您需要在客户端配置中指定行为配置。SVCUtil不会自动生成。这解决了我的问题,现在我成功地使用了Kerberos。虽然这是一个任务!

    <client>           
        <endpoint address="..."               
        binding="customBinding" bindingConfiguration="..."               
        contract="..." name="..."  behaviorConfiguration="ImpersonationBehavior" />                 
        </client>         
        <behaviors>
             <endpointBehaviors>            
             <behavior name="ImpersonationBehavior">               
                  <clientCredentials>                 
                  <windows allowedImpersonationLevel="Impersonation"/>                      </clientCredentials>             
        </behavior>                       
        </endpointBehaviors>                   
        </behaviors> 
    
        4
  •  1
  •   user507040    14 年前

    您应该尝试初始配置,并确保将IIS设置为匿名身份验证和windows身份验证时间。那个原因是当您使用wsHttpBinding时,默认安全性是消息安全性,并且除非您想使用https,否则并没有定义传输安全性。因此Clr声明它需要在IIS上打开匿名身份验证。