【问题标题】:IIS fails to pass windows credentials through to SQL Server for ASP.NET Core appIIS 无法将 Windows 凭据传递到 SQL Server for ASP.NET Core 应用程序
【发布时间】:2019-01-22 22:56:48
【问题描述】:

我在一家拥有 Intranet 和 Windows AD 登录的大公司工作。我们有许多内部 SQL Server 数据库,它们允许我们使用 Windows 身份验证登录,我正在尝试通过 ASP.NET Core 应用程序连接到其中一个。我可以通过 SQL Server Management Studio 连接到这个数据库并很好地查询表。

我尽可能地按照ASP.NET Core app using an existing database 的教程进行操作,并创建了一个模型类来测试我是否可以从数据库中读取数据。在 Visual Studio 中使用 IIS Express 进行调试时,我可以在访问自动生成的控制器和视图时从数据库中读取数据。

调试时一切正常,但发布到 IIS 时,我收到以下错误:

SqlException: Login failed for user '<DOMAIN>\<COMPUTERNAME>$'.

domain 是我的域,computername 是我的计算机名。这是意料之中的,因为我的计算机本身无法访问数据库。但它不应该尝试使用该系统帐户(带有美元符号)进行连接,它应该尝试连接我的 Windows 帐户:&lt;DOMAIN&gt;\&lt;USERNAME&gt;

更奇怪的是,应用程序确实似乎以某种身份识别了我的 Windows 凭据 - 当我访问主页时,我在导航栏中收到熟悉的 "Hello, &lt;DOMAIN&gt;\&lt;USERNAME&gt;!" 消息。因此,Windows 凭据肯定会传递到应用程序,但由于某种原因在尝试通过 DbContext 连接到数据库时没有传递。

我在这里遗漏了什么明显的东西吗?

我的代码

我从 Visual Studio 的 ASP.NET Core Web 应用程序模板开始。

在launchSettings.json中,我有:

  "iisSettings": {
    "windowsAuthentication": true, 
    "anonymousAuthentication": false, 
    "iisExpress": {
      "applicationUrl": "http://localhost:60686",
      "sslPort": 44336
    }
  },

在 appsettings.json 中,我有:

  "ConnectionStrings": {
    "MyDB": "Server=<servername>;Database=<dbname>;Trusted_Connection=True;"
  },

在 Startup.cs 中,ConfigureServices 中有以下行

            services.AddDbContext<MyContext>(options => {
                options.UseSqlServer(Configuration.GetConnectionString("MyDB"));
            });

从那里,我使用实体框架搭建了一个带有视图的 MVC 控制器。

IIS 将 Windows 身份验证设置为 Yes,匿名身份验证设置为 No。我的应用程序池设置为 No Managed Code with ApplicationPoolIdentity。

编辑:问题

为了说明我要解决的实际问题,我在远程 Intranet 服务器上有一个 SQL Server 数据库,它允许通过 Windows 身份验证访问整个公司的子集。如果我想创建一个 ASP.NET 应用程序来为由 IIS 托管的该数据库提供 API,那么最好的方法是什么?假设:

  1. 我不想自己管理权限或以某种方式复制它们
  2. 直接访问数据库的人应该可以访问 API,不应该访问的人不应该。
  3. 如果他们在登录到 Windows 时从 Intranet 中访问它,则不必再次登录。

我以为我可以通过应用程序将他们的 Windows 凭据从 IIS 传递到 SQL Server,但我开始怀疑是否真的是这种情况。

【问题讨论】:

  • 您将应用部署到哪里?您是否尝试过从您将应用程序部署到的机器连接到 sql server?那台机器上有 SSMS 吗?
  • 我会删除“Trusted_Connection=True”设置,因为这是提供机器的凭据。我没有听说过从 IIS->ASP->SQL Server 传递的凭据。似乎您需要在某些时候提供一些凭据。
  • 目前我正在将它部署到本地机器上的 IIS。我已经尝试过文件系统部署和 webdeploy。
  • 您可以尝试使用 NetworkService 而不是 ApplicationPoolIdentity。如果这不起作用...设置一个数据库用户并提供凭据 - 就像一个健全性检查
  • 我的理解是您的数据库连接将使用应用程序池标识(我猜默认为 \$)。我相信你需要使用“模拟”来让它使用你登录的用户docs.microsoft.com/en-us/previous-versions/windows/it-pro/…

标签: asp.net sql-server iis asp.net-core windows-authentication


【解决方案1】:

在了解了更多关于 .NET 以及 Windows auth 在 IIS 上的实际作用之后,我要说的是不推荐我尝试做的事情。将 Windows 凭据传递给 .NET 应用程序以便从中读取,与实际以该用户身份执行辅助进程之间存在差异。后一种情况是我试图做的,但应该在 IIS 中设置我的应用程序池,用户可以登录到数据库,并使用 Windows 凭据来验证具有访问权限的用户列表。

【讨论】:

  • 您是否有实际操作的指南/参考(设置应用程序池等)?
  • 嗨,@Aias 我正在努力在 IIS 中使用 Windows APP 托管 asp.net 核心 Web 应用程序,我被严重卡住了。我已经回答了here 的问题。看起来你能够做到这一点。你能在这方面帮助我吗?如果您知道如何解决此问题,请发布此问题的答案。如果您需要更多详细信息,请随时发表评论。
【解决方案2】:

您正在为 SqlServer 使用实体框架,而 EF 正在使用 ADO.NET SqlClient。因此Trusted_Connection=yes; 不起作用。

改为添加Integrated Security=true;,它应该被修复。

这里有一些资源可以阅读它 https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/connection-string-syntax

【讨论】:

  • 不幸的是,切换连接 Integrated Security=true 不起作用。在尝试使用我的计算机的内置帐户而不是我的实际 Windows 用户进行连接时,仍然会出现相同的错误。这只发生在 IIS 中托管时,而不是在使用 IIS Express 进行调试的开发期间。
  • 我尝试了上面@johnluke.laue 的建议,改用命名用户和密码登录到SQL Server,并且成功了。所以至少提供了一个健全性检查。使用 NetworkService 而不是 ApplicationPoolIdentity 没有帮助。
【解决方案3】:

不要挖掘旧线程,但只要设置了 Identity Impersonate = True,这个函数就应该起作用。这里有一些正在处理的东西。

GitHub Doc

【讨论】:

    【解决方案4】:

    我将添加我的答案,因为这是我解决此问题的方法。
    将“$”符号添加到登录名/用户的原因必须与托管应用程序的 IIS 有关。

    我不是这方面的专家,所以我不能真正深入,但我已将 IIS 用户添加到登录,然后它就可以工作了。

    USE [master]
    GO
    
    CREATE LOGIN [IIS APPPOOL\'name'] FROM WINDOWS WITH DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]
    GO
    
    ALTER SERVER ROLE [sysadmin] ADD MEMBER [IIS APPPOOL\'name']
    GO
    
    ALTER SERVER ROLE [securityadmin] ADD MEMBER [IIS APPPOOL\'name']
    GO
    
    ALTER SERVER ROLE [serveradmin] ADD MEMBER [IIS APPPOOL\'name']
    GO
    
    ALTER SERVER ROLE [setupadmin] ADD MEMBER [IIS APPPOOL\'name']
    GO
    
    ALTER SERVER ROLE [processadmin] ADD MEMBER [IIS APPPOOL\'name']
    GO
    
    ALTER SERVER ROLE [diskadmin] ADD MEMBER [IIS APPPOOL\'name']
    GO
    
    ALTER SERVER ROLE [dbcreator] ADD MEMBER [IIS APPPOOL\'name']
    GO
    
    ALTER SERVER ROLE [bulkadmin] ADD MEMBER [IIS APPPOOL\'name']
    GO  
    

    您必须将“名称”更改为您的 IIS 托管应用程序名称。因此,例如,如果您在 ISS 中的应用/网站名称是“My-Backend-App”,您应该这样做:

    CREATE LOGIN [IIS APPPOOL\My-Backend-App] FROM WINDOWS ...  
    

    所以所有的名字都应该是“My-Backend-App”。

    当将此用户添加到登录时,我的后端应用程序可以访问和创建数据库、创建表、访问数据等...

    旁注:我已使用 Windows 事件记录器找出这是我的问题。我的应用程序刚刚崩溃,出现“500.30”错误,但没有给出真实信息。

    您可以从 Windows 搜索访问“事件查看器”应用程序。然后您可以转到“应用程序”,您的机器上发生了所有应用程序错误/崩溃,在这种情况下也是原因。它说在尝试登录 SQL 时找不到用户“myUser$”,但 Windows 身份验证用户是“myUser”。所以由于某种原因,它添加了一个“$”符号并且无法登录。我上面的修复解决了这个问题,你可以登录等等。

    【讨论】:

      猜你喜欢
      • 2018-11-10
      • 1970-01-01
      • 1970-01-01
      • 2022-06-19
      • 1970-01-01
      • 2021-02-09
      • 2017-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多