WCF和Kerberos身份验证 [英] WCF and Kerberos Authentication

查看:127
本文介绍了WCF和Kerberos身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了许多msdn文章和codeplex指南,但是无法使WCF与Kerberos身份验证和委派一起使用,希望能有所帮助.

I have followed numerous msdn articles and the codeplex guidance but cannot get WCF to work with Kerberos authentication and delegation and would appreciate a little help.

设置

我在远程计算机上的IIS网站中拥有WCF服务

I have the WCF service in an IIS website on a remote machine

  • Windows 2003 R2-SP 2上的IIS 6.0
  • 已添加计算机的SPN(http/myserver&& http/myserver:8080)
  • 已为IIS应用程序池创建了一个AD帐户
  • AD帐户具有以下设置:允许委派(对于Kerberos),设置为true

我正在使用

I am using Brian Booth's debug site on 8080 and the site passes all requirements for Kerberos delegation. The debug IIS site has anonymous authentication off, and Integrated Windows authentication on.

我已将这些设置镜像到托管WCF服务的站点.

I have mirrored these settings to the site hosting the WCF service.

Web服务-Web配置(原始)

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

网络服务-网络方法

[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>

应用程序错误

当我的测试应用程序WinForms应用程序尝试调用Web方法时,发生以下错误:

The following error occurs when my test application, a WinForms app, tries to call the web method:

"HTTP请求被未经授权 客户认证方案 '匿名的'.认证头 从服务器收到的是 谈判,NTLM".

"The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'."

事件日志

事件日志中出现以下错误:

The following error is in the event log:

例外: System.ServiceModel.ServiceActivationException: 服务"/Service.svc"不能为 由于期间发生异常而被激活 汇编.异常消息 是:此服务的安全设置 需要匿名"身份验证,但 IIS未启用它 托管此服务的应用程序.

Exception: System.ServiceModel.ServiceActivationException: The service '/Service.svc' cannot be activated due to an exception during compilation. The exception message is: Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.

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

Which I don't understand. The whole point of this service is to not allow anonymous authentication, every user/request must be authenticated using Kerberos tickets, then passing them through to other machines.

如何为Kerberos身份验证和委派配置此WCF服务?

How should I configure this WCF service for Kerberos authentication and delegation?

修订版1

在阅读此SO问题后,我删除了元数据终结点.这尚未解决问题.

After reading this SO question I removed the metadata endpoint. This has not resolved the issue.

修订版2

经过更多研究,我发现了一些建议将wsHttpBinding更改为basicHttpBinding的帖子.对web.config的该部分的修改已包含在下面,并且服务端点已更新为引用该绑定.

After more researching I found a few posts suggesting to change wsHttpBinding to basicHttpBinding. The modification to that portion of the web.config has been included below, and the service endpoint has been updated to refer to that binding.

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>
<!-- ... -->

错误(已修订)

当前错误看起来像它包含一个Kerberos身份验证标头.

The current error looks like it contains a Kerberos authentication header.

HTTP请求未经授权 客户认证方案 '谈判'.认证头 从服务器收到的是 '协商SOMEHUGESCARYKEYHERE

The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate SOMEHUGESCARYKEYHERE

推荐答案

对我来说,当前设置确实有效:

For me the current setup does work:

在服务器上:

<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的所有方法上设置以下属性:

Set the following attribute on all methods for the 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>

HTH,斯文

这篇关于WCF和Kerberos身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆