3

开发一个 MVC 站点来处理跟踪数据。目标是使用 MVC4 并部署到运行 SQL Server 2008 和 IIS 7.5 的 Windows 2008 R2 Server。这是在域中运行的。

有效的原始设置是使用 Visual Studio 2012.2 运行 Windows 8、IIS 8(非 express)并与远程 SQL 服务器通信的开发机器。没有使用 Developer Server 进行开发。我能够连接到网站、运行任何东西等,而在任何日志中都没有明显的问题。

自从部署到 2008 服务器和 IIS 7.5 后,问题就出现了。使用映射到ApplicationPoolIdentity的DefaultAppPool,我创建了一个带有 Binding *:80 的网站并附加了部署。设置如下:

Application pool: DefaultAppPool
.Net Framework Version: 4.0
Pipeline Mode: Integrated
Pass-through authentication.

测试设置显示消息“应用程序池标识有效”。我向网站添加了一个虚拟目录,测试设置显示相同的消息。我将目录转换为应用程序和测试设置现在显示错误消息“无效的应用程序路径”。如果我使用自己的凭据,则测试设置显示有效。

从远程服务器网站上的 IIS-> 应用程序-> 操作-> 浏览 *:80 我会自动收到我的主页。浏览到包含对 sql 服务器的调用的页面会给我一个错误 401.2,它可以追溯到远程计算机上的 404。

我在 IIS 服务器上安装了 Windows 身份验证,我在 SQL 中为IIS AppPool\DefaultAppPool. 我添加了相同的访问作为用户db_readerdb_writer数据库。我将身份添加到网站虚拟目录的读/写和执行权限。

我已经阅读了我在搜索中可以找到的所有内容,并且所有内容都表明问题是没有安装 Windows 身份验证或需要运行aspnet_regiis -i......但我做了所有这一切!我确定这是一个配置问题,但我只是想不通,并且在过去两天试图解决这个问题已经筋疲力尽了。

Web.config 部分如下:

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <configSections>

    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
  <appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>
    <httpRuntime targetFramework="4.5" />
    <authentication mode="Windows" />
    <authorization>
      <deny users="?" />
    </authorization>
    <pages>
      <namespaces>
        <add namespace="System.Web.Helpers" />
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.WebPages" />
      </namespaces>
    </pages>
    <identity impersonate="true" />
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <remove name="TestAsyncHttpHandler" />
      <add name="TestAsyncHttpHandler" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /></handlers>
        <modules>
            <remove name="WebDAVModule" />
        </modules>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.4.0.0" newVersion="5.4.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.4.0.0" newVersion="5.4.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Spatial" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.4.0.0" newVersion="5.4.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  </entityFramework>
  <connectionStrings>
    <add name="PerfTrendDataEntities" connectionString="metadata=res://*/Models.PerfTrendDBModel.csdl|res://*/Models.PerfTrendDBModel.ssdl|res://*/Models.PerfTrendDBModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=perftrenddb;initial catalog=PerfTrendData;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="TrendRestServiceBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="PerformanceTrendDB.Web.SubmitResults.TrendRestService" behaviorConfiguration="TrendRestServiceBehavior">
        <endpoint name="BasicHttp" address="basic" binding="basicHttpBinding" bindingConfiguration="FileUploadConfig" contract="PerformanceTrendDB.Web.SubmitResults.ITrendRestService" />
      </service>
    </services>
    <bindings>
      <basicHttpBinding>
        <binding name="FileUploadConfig" transferMode="StreamedRequest" />
      </basicHttpBinding>
    </bindings>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>

所有这些配置都适用于我的开发盒上的 IIS 8,我不确定迁移到 IIS 7.5 是否应该有很大的不同,我相当确定从新机器。

编辑:添加了日志文件和跟踪文件

操作流程,打开网站并点击 ManageUsers 链接。管理用户负载然后 api 调用失败。看起来很多错误发生在浏览器尝试最初使用匿名,然后使用凭据登录......所以配置中的两个错误来修复它看起来像。

日志文件显示:

2013-10-16 03:05:37 10.23.34.146 GET /PerformanceData - 80 - 10.24.158.125 Mozilla/5.0+(Windows+NT+6.2;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/30.0.1599.69+Safari/537.36 401 2 5 609
2013-10-16 03:05:39 10.23.34.146 GET /PerformanceData - 80 AMR\gjmason 10.24.158.125 Mozilla/5.0+(Windows+NT+6.2;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/30.0.1599.69+Safari/537.36 200 0 0 2281
2013-10-16 03:07:01 10.23.34.146 GET /PerformanceData/Home/ManageUsers - 80 - 10.24.158.125 Mozilla/5.0+(Windows+NT+6.2;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/30.0.1599.69+Safari/537.36 401 2 5 15
2013-10-16 03:07:01 10.23.34.146 GET /PerformanceData/Home/ManageUsers - 80 AMR\gjmason 10.24.158.125 Mozilla/5.0+(Windows+NT+6.2;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/30.0.1599.69+Safari/537.36 200 0 0 484
2013-10-16 03:07:03 10.23.34.146 GET /perftrenddb/api/UserManagement - 80 - 10.24.158.125 Mozilla/5.0+(Windows+NT+6.2;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/30.0.1599.69+Safari/537.36 401 2 5 1015
2013-10-16 03:07:03 10.23.34.146 GET /perftrenddb/api/UserManagement - 80 AMR\gjmason 10.24.158.125 Mozilla/5.0+(Windows+NT+6.2;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/30.0.1599.69+Safari/537.36 404 0 2 296

压缩片段中显示的跟踪文件:

Summary (1st error)
Url: http://perftrenddb:80/PerformanceData/Home/ManageUsers 
App Pool: DefaultAppPool 
Authentication: NOT_AVAILABLE 

Summary (2nd error - same details)
Url: http://perftrenddb:80/perftrenddb/api/UserManagement 
App Pool: ASP.NET v4.0 Classic 
Authentication: NOT_AVAILABLE 

Summary (3rd error - from a STATUS_CODE 404)
Url: http://perftrenddb:80/perftrenddb/api/UserManagement 
App Pool: ASP.NET v4.0 Classic 
Authentication: Negotiate 

那么三件事?

  1. 尝试以匿名用户身份登录,还是模拟尝试?普通的?
  2. (已修复,请参阅解决方案 2)api 调用将是http://perftrenddb:80/perftrenddb/api/UserManagement,而不是我设置它的方式,而不是它在我的本地计算机上运行的方式。
  3. App Pool 更改为 Classic 而不是使用 Integrated Pipeline 的 DefaultAppPool,这是一个问题吗?

我可以回答第二个和第三个错误跟踪,因为那个在 JS 文件中。当我让它在开发环境中工作时是我的错(这是我第一次涉足 Web 开发,我通常坚持使用应用程序库!)。我确实有这部分的解决方案......它已经让我的网站正常工作,尽管我仍然收到关于第一个问题的错误/跟踪以及我不明白的应用程序池转换。

我讨厌我不明白的奇怪问题,所以任何解决 401.2 匿名登录问题的见解都会很棒!

解决方案 2 要为我们的菜鸟修复对我们的虚拟目录名称进行硬编码的上下文前缀,有一个修复程序可以消除 Developer Server/IIS Express/IIS 部署问题。

将此添加到您的_Layout.cshtml或母版页:

    <script type="text/javascript">
        var config = {
            contextPath: '@Url.Content("~")'
        }
    </script>

然后在你的 JS 文件中添加:

var apiUri = config.contextPath + "api/MyWebApi";

MyWebApi您正在访问的 API 控制器的名称在哪里。你现在可以毫无问题地打电话给你getJSON,即

$.getJSON(apiUri, null).success( /* Your code */ );
4

1 回答 1

1

据我了解,我可以在微软网站上看到 401.2 错误是因为

未尝试身份验证,因为服务器和客户端无法就身份验证协议达成一致

我也可以猜测权限也可能有问题。

您可以使用微软提供的以下工具来诊断问题

身份验证和访问控制诊断 1.0

IIS 诊断工具包

希望这可能对面临同样问题的人有所帮助。

于 2014-02-07T13:24:47.310 回答