在 IIS 中禁用匿名身份验证后 WebServiceHost 无法正常工作

Posted

技术标签:

【中文标题】在 IIS 中禁用匿名身份验证后 WebServiceHost 无法正常工作【英文标题】:WebServiceHost not working after disabling anonymous authentication in IIS 【发布时间】:2020-07-30 15:21:17 【问题描述】:

我有一个与 asp.net 集成并部署在 IIS 中的 rest wcf 服务。这在启用匿名身份验证时工作正常。当它被禁用时,当我在邮递员中使用 rest api 调用时,它会引发 401 错误。在 IIS 中启用匿名身份验证和表单身份验证。现在我禁用了匿名和表单并仅启用了 Windows 身份验证。 我的代码如下:

public class SampleWebServiceHostFactory : WebServiceHostFactory
    
        private Type ContractServiceType;
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public SampleWebServiceHostFactory(Type contractServiceType):base()
                    
            ContractServiceType = contractServiceType;
        

        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
                    
            WebServiceHost host = (WebServiceHost)base.CreateServiceHost(serviceType,baseAddresses);


            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            WebHttpBinding mybinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
            mybinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

            mybinding.MaxReceivedMessageSize = 2147483647;
            mybinding.TransferMode = TransferMode.StreamedRequest;
            mybinding.ReaderQuotas.MaxDepth = 1204;
            mybinding.ReaderQuotas.MaxStringContentLength = 2147483647;
            mybinding.ReaderQuotas.MaxArrayLength = 2147483647;
            mybinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
            mybinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
            mybinding.SendTimeout = new TimeSpan(4,0,0);
            mybinding.ReceiveTimeout = new TimeSpan(4,0,0);

            host.AddServiceEndpoint(ContractServiceType, mybinding, "");
            host.Description.Behaviors.Add(new RestServiceBehavior());
            log.Info("Testing1");
            return host;
        
    

配置文件中的以下代码

<system.serviceModel>
    <client/>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
          <serviceDebug httpHelpPageEnabled="false" httpsHelpPageEnabled="false" includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
        </binding>
      </webHttpBinding>
    </bindings>
  </system.serviceModel>

我已启用登录 Global.asax 以查看问题发生在哪里。在 Session_Start 方法触发后,我在上面的代码中看到了日志行“Testing1”。之后没有记录,它在邮递员中抛出 401 错误,当我在浏览器中使用 url 时继续询问用户名和密码。

【问题讨论】:

请阅读Under what circumstances may I add "urgent" or other similar phrases to my question, in order to obtain faster answers?并找出为什么它经常会产生相反的效果。 【参考方案1】:

既然我们已经在WebServiceHostFactory的构造函数中设置好了配置,就不用再单独在配置文件中进行配置了。

      <webHttpBinding>
    <binding receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
      <readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
    </binding>
  </webHttpBinding>

我建议您参考下面的Windows身份验证配置。

  <system.serviceModel>
    <services>
      <service name="WcfService3.Service1">
        <endpoint address="" behaviorConfiguration="rest" contract="WcfService3.IService1" binding="webHttpBinding" bindingConfiguration="https"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    <endpointBehaviors>
      <behavior name="rest">
        <webHttp helpEnabled="true"/>
      </behavior>
    </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="https">
          <security mode="Transport">
            <transport clientCredentialType="Windows">
            </transport>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
  </system.serviceModel>

之后,禁用 IIS 中的其他身份验证模式。我们需要在调用服务时提供一对 Windows 凭据。 凭据实际上是服务器端的windows帐户,它使我们能够访问网站。 如果问题仍然存在,请随时告诉我。

【讨论】:

以上是关于在 IIS 中禁用匿名身份验证后 WebServiceHost 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

webDAV IIS6 身份验证不适用于匿名禁用

使用 Powershell 3.0 切换 IIS 7.5 身份验证“匿名身份验证”?

WCF - Windows 身份验证 - 安全设置需要匿名

如何禁用 WCF 数据服务的身份验证方案

匿名之前的 IIS Windows 身份验证

IIS 身份验证