1. 程式人生 > >WCF : 修復 Security settings for this service require Windows Authentication but it is not enabled for the IIS application that ho

WCF : 修復 Security settings for this service require Windows Authentication but it is not enabled for the IIS application that ho

摘要 : 最近遇到了一個奇怪的 WCF 安全配置問題, WCF Service 上面配置了Windows Authentication. IIS上也啟用了 Windows Authentication, 但是仍然出現IIS沒有啟用Windows Authentication的問題. 在網路上能查到的資料很少. 通過自己的troubleshooting發現所遇到的錯誤提示比較具有迷惑性. 所以POST上來給大家分享一下.

問題 :

 最近遇到了一個奇怪的 WCF 安全配置問題, WCF Service 上面配置了Windows Authentication. IIS上也啟用了 Windows Authentication, 但是仍然出現IIS沒有啟用Windows Authentication的問題.  然而在啟動這個WCF Service的時候遇到了如下的錯誤. 

Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service. 
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NotSupportedException: Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.
Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. Stack Trace: [NotSupportedException: Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.] System.ServiceModel.Channels.HttpChannelListener.ApplyHostedContext
(VirtualPathExtension virtualPathExtension, Boolean isMetadataListener) +15710645 System.ServiceModel.Channels.HttpsChannelListener.ApplyHostedContext(VirtualPathExtension virtualPathExtension, Boolean isMetadataListener) +27 System.ServiceModel.Channels.HttpsTransportBindingElement.BuildChannelListener(BindingContext context) +105 System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +95 System.ServiceModel.Channels.MessageEncodingBindingElement.InternalBuildChannelListener(BindingContext context) +102 System.ServiceModel.Channels.TextMessageEncodingBindingElement.BuildChannelListener(BindingContext context) +70 System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +95 System.ServiceModel.Channels.Binding.BuildChannelListener(Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters) +166 System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener(Boolean actuallyCreate, Type[] supportedChannels, Binding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, ServiceThrottle throttle, IChannelListener& result, Boolean supportContextSession) +399 System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result) +499 System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) +1937 System.ServiceModel.ServiceHostBase.InitializeRuntime() +61 System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +63 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +563 System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +135 System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +654 [ServiceActivationException: The service '/WinAuthService.svc' cannot be activated due to an exception during compilation. The exception message is: Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service..] System.ServiceModel.AsyncResult.End(IAsyncResult result) +15786048 System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +15706393 System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication context, Boolean flowContext) +265 System.ServiceModel.Activation.HttpModule.ProcessRequest(Object sender, EventArgs e) +227 System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +171

下面是這個WCF Service的配置. 按照這個配置, 是需要在IIS上啟用Windows Authentication.

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="myBasicBinding">
                <security mode="Transport">
                    <transport clientCredentialType="Windows" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <services>
        <service name="WCFSample.WinAuthService">
            <endpoint address="WinAuthService.svc" binding="basicHttpBinding"
                bindingConfiguration="myBasicBinding" contract="WCFSample.IWinAuthService" />
        </service>
    </services>
</system.serviceModel>

在IIS的管理介面上, 已經按照啟用了Windows Authentication並且禁用了Anonymous Authentication. 

image

分析 :

報錯資訊的最頂上一條已經提示了丟擲這個異常的CALL STACK 是 System.ServiceModel.Channels.HttpChannelListener.ApplyHostedContext. 因為是託管程式碼, 所以用工具ILSPY來檢查這段程式碼看什麼情況下會丟擲這樣的錯誤. 從程式碼上看, 這個異常是在做了一定邏輯的校驗之後, 主動丟擲來.

internal override void ApplyHostedContext(VirtualPathExtension virtualPathExtension, bool isMetadataListener)
        {
            ServiceNameCollection customServiceNames;
            base.ApplyHostedContext(virtualPathExtension, isMetadataListener);
            AuthenticationSchemes authenticationSchemes = HostedTransportConfigurationManager.MetabaseSettings.GetAuthenticationSchemes(base.HostedVirtualPath);
            if (this.AuthenticationScheme == AuthenticationSchemes.Anonymous && (authenticationSchemes & AuthenticationSchemes.Anonymous) == AuthenticationSchemes.None && isMetadataListener)
            {
                if ((authenticationSchemes & AuthenticationSchemes.Negotiate) == AuthenticationSchemes.None)
                {
                    this.authenticationScheme = authenticationSchemes;
                }
                else
                {
                    this.authenticationScheme = AuthenticationSchemes.Negotiate;
                }
            }
            if ((authenticationSchemes & this.AuthenticationScheme) == AuthenticationSchemes.None)
            {
                if (!AuthenticationSchemesHelper.IsWindowsAuth(this.AuthenticationScheme))
                {
                    ExceptionUtility exceptionUtility = DiagnosticUtility.ExceptionUtility;
                    object[] str = new object[] { this.AuthenticationScheme.ToString() };
                    throw exceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString("Hosting_AuthSchemesRequireOtherAuth", str)));
                }
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString("Hosting_AuthSchemesRequireWindowsAuth")));
            }
            if (this.AuthenticationScheme != AuthenticationSchemes.Anonymous)
            {
                ExtendedProtectionPolicy extendedProtectionPolicy = HostedTransportConfigurationManager.MetabaseSettings.GetExtendedProtectionPolicy(base.HostedVirtualPath);
                if (extendedProtectionPolicy == null)
                {
                    if (this.extendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.Always)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString("ExtendedProtectionNotSupported")));
                    }
                }
                else if (!isMetadataListener || !ChannelBindingUtility.IsDefaultPolicy(this.extendedProtectionPolicy))
                {
                    ChannelBindingUtility.ValidatePolicies(extendedProtectionPolicy, this.extendedProtectionPolicy, true);
                    if (this.usingDefaultSpnList)
                    {
                        customServiceNames = null;
                    }
                    else
                    {
                        customServiceNames = this.extendedProtectionPolicy.CustomServiceNames;
                    }
                    if (!ChannelBindingUtility.IsSubset(extendedProtectionPolicy.CustomServiceNames, customServiceNames))
                    {
                        object[] objArray = new object[] { SR.GetString("Hosting_ExtendedProtectionSPNListNotSubset") };
                        string str1 = SR.GetString("Hosting_ExtendedProtectionPoliciesMustMatch2", objArray);
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(str1));
                    }
                }
                else
                {
                    this.extendedProtectionPolicy = extendedProtectionPolicy;
                }
            }
            if (!ServiceHostingEnvironment.IsSimpleApplicationHost)
            {
                this.realm = HostedTransportConfigurationManager.MetabaseSettings.GetRealm(virtualPathExtension.VirtualPath);
            }
        }

不過由於不是我們確切看到的錯誤. 所以需要在DLL的Resources中確切的驗證一下. 在這裡明確

image

Hosting_AuthSchemesRequireWindowsAuth=Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.

往上判斷, 能夠進入到 if ((authenticationSchemes & this.AuthenticationScheme) == AuthenticationSchemes.None) . AuthenticationSchemes是一個列舉型別. 在這裡注意到了有兩個分開的定義, NegotiateNtlm. 在 IIS Windows Authentication 可以配置多個Provider. 預設情況下有2個, 分別是NegotiateNTLM.

namespace System.Net
{
    /// <summary>Specifies protocols for authentication.</summary>
    [Flags]
    public enum AuthenticationSchemes
    {
        /// <summary>No authentication is allowed. A client requesting an <see cref="T:System.Net.HttpListener" /> object with this flag set will always receive a 403 Forbidden status. Use this flag when a resource should never be served to a client.</summary>
        None = 0,
        /// <summary>Specifies digest authentication.</summary>
        Digest = 1,
        /// <summary>Negotiates with the client to determine the authentication scheme. If both client and server support Kerberos, it is used; otherwise, NTLM is used.</summary>
        Negotiate = 2,
        /// <summary>Specifies NTLM authentication.</summary>
        Ntlm = 4,
        /// <summary>Specifies Windows authentication.</summary>
        IntegratedWindowsAuthentication = 6,
        /// <summary>Specifies basic authentication. </summary>
        Basic = 8,
        /// <summary>Specifies anonymous authentication.</summary>
        Anonymous = 32768
    }
}

在得到這些線索之後, 檢查了Windows Authentication的Providers. 果然只有一個NTLM. 添加了一個新的Negotiate 的 Provider之後, WCF Service就得到了解決.

image

結論 :

這篇文章中僅討論其中一種可能造成這樣問題的情況. 這裡我遇到的問題與Windows Authentication的Provider有關係.

當 WCF Service 上啟用了Transport 層面上的安全設定之後, 可以配置某一種型別的ClientCredentialType. 其中可以包括 None, Basic, Digest, Ntlm, Windows, Certificate 和 Password. 

當指定為Windows的時候, 實質是要求Kerboer或者NTLM兩者皆可. Server先去嘗試Kerberos驗證, 如果Kerberos驗證失敗, 則會嘗試通過NTLM. 也可以通過設定另外的屬性 AllowNtlm為false來強制使用Kerberos. Kerberos和Ntlm是兩種不同的驗證方式.

由於這一點的不同, 在IIS上要確保做出相應的配置. 即, 開啟IIS的Windows Authentication的同時, 要確保Negotiate Provider也在列表中. 只有Ntlm會被認為是錯誤的配置.

可以參考這裡的連結 :

  • http://blogs.msdn.com/b/benjaminperkins/archive/2011/09/14/iis-integrated-windows-authentication-with-negotiate.aspx

Sonic Guo

相關推薦

WCF : 修復 Security settings for this service require Windows Authentication but it is not enabled for the IIS application that ho

摘要 : 最近遇到了一個奇怪的 WCF 安全配置問題, WCF Service 上面配置了Windows Authentication. IIS上也啟用了 Windows Authentication, 但是仍然出現IIS沒有啟用Windows Authentication的問題. 在網路上能查到的資料很少.

Node.js使用MongoDB3.4+Access control is not enabled for the database解決方案

今天使用MongoDB時遇到了一些問題 建立資料庫連線時出現了warnings 出現這個警告的原因是新版本的MongDB為了讓我們建立一個安全的資料庫 必須要進行驗證 後來在外網找到了答案 解決方案如下: 建立管理員 use admin d

Version 1.7.0_80 of the JVM is not suitable for this product.Version: 1.8 or greater is required.

2種 方法 mar 技術 bin 啟動 product 分享圖片 1.7 Eclipse啟動失敗,設置eclipse啟動jdk有2種方法 第一種: 直接安裝eclipse對應的jdk版本,並設置環境變量 第二種: 修改eclipse配置文件eclipse.ini

Version 1.5 of the JVM is not suitable for this product.Version:1.6 or greater is required

近期在公司涉及到了伺服器等的擴充套件,smartfoxserver擴充套件使用的Eclipse,儘管沒學過java。可是咱畢竟是C++起價的,其它語言看看也就會了,專案依然做著,近期看到某同學有一些java的問題,小問題就隨便在公司幫忙攻克了下,只是後來有個專案發現有些麻煩,準備下班後再看

appium解決無法通過name屬性識別元素org.openqa.selenium.InvalidSelectorException: Locator Strategy 'name' is not supported for this session

執行程式碼、: public AndroidDriver<AndroidElement> appiumDriver; appiumDriver.findElement(By.name("我的")).click(); 報錯如下:   去到appium安裝目錄下,找到appiu

Version 當前jdk版本號 of the JVM is not suitable for the this product.Version:1.8 or greater is required

eclipse對應的jdk版本打不開 解決辦法一:可以更改jdk版本。 解決辦法二:我們要知道 JRE是java執行時環境,包含了java虛擬機器,java基礎類庫。是使用java

Version xx of the JVM is not suitable for this product

在官網下載了linux eclipse 4.5版本,檔案為eclipse-cpp-mars-R-linux-gtk-x86_64.tar.gz 執行eclipse時出現類似下面提示:  Version 1.6.0_22 of the JVM is not suitab

解決VERSION 1.7 OF THE JVM IS NOT SUITABLE FOR THIS PRODUCT.

在新環境安裝eclipse時有時候會出現 “version 1.7 of the jvm is not suitable for this product. version 1.8 greater is required for eclipse”的問題. 導致eclipse

IDEA:Cannot start compiler:the SDK is not specified for module...錯誤修復

IDEA出現報錯 解決方法: 一、在Project Structure中選擇SDKs,點選右側的+號 二、選擇JDK,後找到JDK的安裝位置,點選應用。 三、在Project中的Project SDK中選擇剛剛新增的JDK,點選應用 問題解決

WCF The service cannot be activated because it does not support ASP.NET compatibility

測試釋出到虛擬目錄中時發生的報錯現象,由於不支援asp.net相容性而導致服務無法啟用啟用。具體錯誤資訊如下:Server Error in '/Service2' Application. ------------------------------------------

啟動eclipse彈出提示Version 1.7.0_79 of the JVM is not suitable for this product. Version: 1.8 or greater is required怎樣解決

server bubuko 出現 lock http version req program eclipse 啟動eclipse時彈出如下彈出框: 解決辦法: 在eclipse安裝目錄下找到eclipse.ini文件,並在 -vmargs-Dosgi.requiredJ

Warning: date(): It is not safe to rely on the system's timezone settings.

bsp ron notice zone asi 警告 family one str PHP調試的時候出現了警告: It is not safe to rely on the system解決方法,其實就是時區設置不正確造成的,本文提供了3種方法來解決這個問題。 實際上,

Eclipse '<>' operator is not allowed for source level below 1.7

source for nbsp 技術 operator cnblogs eclips 解決方法 src ‘<>‘ operator is not allowed for source level below 1.7 解決方法: Eclipse '

MySQL Strict Mode is not set for database connection 'default'

bsp tran sql col set class spa clas log SET GLOBAL sql_mode=‘strict_trans_tables‘; SET sql_mode =‘strict_trans_tables‘; MySQ

解決“This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms”

policy font edi config 分享 his 內容 class crypto 解決“This implementation is not part of the Windows Platform FIPS validated cryptographic alg

iOS打包上傳ipa文件時,報錯<ERROR ITMS-90096: "Your binary is not optimized for iPhone 5 - New iPhone apps......>的解決方案

splay update 分享圖片 trait tin log .com bmi graphic 很長一段時間習慣了用企業級證書發布,最近的新項目使用Xcode 9.1發布到AppStore時遇到了一個小問題(emm..其實問題跟Xcode版本沒關系,我也不知道為什麽要聲明

org.mongodb.morphia.query.QueryException: sorting is not allowed for updates.

model ica -a inline operation per ati round 限制 代碼: public UpdateResults updateProductByChannel(String channelId, String channelName){

mognodb 分片出現{ "code" : 20, "ok" : 0, "errmsg" : "sharding not enabled for db " }

mongos> sh.shardCollection("mf.mb_device_login_log",{"_plat" : 1,"_uid" : 1,"_tm" : 1}) { "code" : 20, "ok" : 0, "errmsg" : "sharding not ena

elasticsearch6.4 memory locking requested for elasticsearch process but memory is not locked

[2018-10-18T05:28:57,713][ERROR][o.e.b.Bootstrap ] [node-45] node validation exception[1] bootstrap checks failed[1]: memory locking requested for elastics

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use

方法一:在程式碼中加入 date_default_timezone_set("PRC");即可 date_default_timezone_set('PRC')表示設定中國時區 方法二 :在配置檔案php.ini中修改配置 在php.ini里加上找到date.timez