简体   繁体   English

IIS 无法将 Windows 凭据传递到 SQL Server for ASP.NET Core 应用程序

[英]IIS fails to pass windows credentials through to SQL Server for ASP.NET Core app

I work for a large company with an intranet and Windows AD logins for everyone.我在一家大公司工作,每个人都有一个 Intranet 和 Windows AD 登录。 We have a number of internal SQL Server databases which allow us to log in using Windows authentication, one of which I'm trying to connect to through an ASP.NET Core application.我们有许多内部 SQL Server 数据库,它们允许我们使用 Windows 身份验证登录,我正在尝试通过 ASP.NET Core 应用程序连接到其中之一。 I can connect to this database through SQL Server Management Studio and query the tables fine.我可以通过 SQL Server Management Studio 连接到这个数据库并很好地查询表。

I've followed the tutorial for an ASP.NET Core app using an existing database as closely as I possibly could, and created a single model class to test with to see if I could read data from the database.我尽可能地遵循了使用现有数据库ASP.NET Core 应用程序教程,并创建了一个模型类来测试,看看我是否可以从数据库中读取数据。 When debugging with IIS Express in Visual Studio, I can read data from the database when accessing the auto-generated controller and views.在 Visual Studio 中使用 IIS Express 进行调试时,我可以在访问自动生成的控制器和视图时从数据库中读取数据。

Everything seems fine when debugging, but when publishing to IIS, I receive the following error:调试时一切正常,但发布到 IIS 时,我收到以下错误:

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

Where domain is my domain and computername is my computer's name.其中 domain 是我的域,computername 是我的计算机名称。 This is expected, since my computer itself doesn't have access to the database.这是意料之中的,因为我的计算机本身无法访问数据库。 But it shouldn't be trying to connect using that system account (with the dollar sign), it should be trying to connect with my windows account: <DOMAIN>\\<USERNAME> .但它不应该尝试使用该系统帐户(带有美元符号)进行连接,它应该尝试与我的 Windows 帐户连接: <DOMAIN>\\<USERNAME>

What's weirder, the app does seem to recognize my Windows credentials in some capacity - when I access the home page, I get the familiar "Hello, <DOMAIN>\\<USERNAME>!"更奇怪的是,该应用程序似乎确实以某种身份识别了我的 Windows 凭据 - 当我访问主页时,我得到熟悉的"Hello, <DOMAIN>\\<USERNAME>!" message in the nav bar.导航栏中的消息。 So the Windows credentials are definitely getting passed through to the app, but for some reason not getting passed through when trying to connect to the database through DbContext.因此,Windows 凭据肯定会传递给应用程序,但由于某种原因,在尝试通过 DbContext 连接到数据库时未通过。

Am I missing something obvious here?我在这里遗漏了一些明显的东西吗?

My Code我的代码

I started with Visual Studio's ASP.NET Core Web Application template.我从 Visual Studio 的 ASP.NET Core Web 应用程序模板开始。

In launchSettings.json, I have:在launchSettings.json中,我有:

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

In appsettings.json, I have:在 appsettings.json 中,我有:

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

In Startup.cs, I have the following line in ConfigureServices在 Startup.cs 中,我在ConfigureServices有以下行

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

And from there, I have scaffolded an MVC controller with views using Entity Framework.从那里开始,我使用实体框架搭建了一个带有视图的 MVC 控制器。

IIS has Windows authentication set to Yes and anonymous authentication set to No. My application pool is set to No Managed Code with ApplicationPoolIdentity. IIS 将 Windows 身份验证设置为“是”,将匿名身份验证设置为“否”。我的应用程序池使用 ApplicationPoolIdentity 设置为“无托管代码”。

Edit: The problem编辑:问题

To state the actual problem I'm trying to solve, I have a SQL Server database on a remote intranet server which allows access to a subset of the whole company via Windows authentication.为了说明我试图解决的实际问题,我在远程 Intranet 服务器上有一个 SQL Server 数据库,它允许通过 Windows 身份验证访问整个公司的一个子集。 If I want to create an ASP.NET application to provide an API to that database, hosted by IIS, what's the best way to do this?如果我想创建一个 ASP.NET 应用程序来为该数据库提供 API,由 IIS 托管,那么最好的方法是什么? Assuming:假设:

  1. I don't want to have to manage permissions myself or have to duplicate them in some way我不想自己管理权限或必须以某种方式复制它们
  2. The people who have access to the database directly should have access to the API, the people who don't should not.直接访问数据库的人应该可以访问 API,没有的人不应该。
  3. If they're accessing it from within the intranet while logged in to Windows, they shouldn't have to log in again.如果他们在登录到 Windows 时从 Intranet 中访问它,则他们不必再次登录。

I assumed I could just pass their windows credentials from IIS through the app to SQL server but I'm starting to wonder if that's actually the case.我以为我可以通过应用程序将他们的 Windows 凭据从 IIS 传递到 SQL 服务器,但我开始怀疑是否确实如此。

You are using Entity-Framework for SqlServer and EF is using ADO.NET SqlClient.您正在为 SqlServer 使用实体框架,而 EF 正在使用 ADO.NET SqlClient。 Therefore Trusted_Connection=yes;因此Trusted_Connection=yes; does not work.不起作用。

Add Integrated Security=true;添加Integrated Security=true; instead and it should be fixed.相反,它应该被修复。

Here some resources to read about it https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/connection-string-syntax这里有一些资源可以阅读https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/connection-string-syntax

After learning more about .NET and what Windows auth actually does on IIS, I'm going to say that what I was trying to do is not recommended.在详细了解 .NET 以及 Windows 身份验证在 IIS 上实际执行的操作后,我要说不推荐我尝试执行的操作。 There is a difference between passing windows credentials to a .NET app in order to read from them, vs. actually executing a secondary process as that user.将 Windows 凭据传递给 .NET 应用程序以读取它们与实际以该用户身份执行辅助进程之间存在差异。 The latter case is what I was trying to do, but instead should set up my app pool in IIS with a user who can log in to the database, and use the windows credentials to verify against the list of users who have access.后一种情况是我想要做的,但应该在 IIS 中使用可以登录数据库的用户设置我的应用程序池,并使用 Windows 凭据来验证具有访问权限的用户列表。

Not to dig up an old thread, but this is a function that should work as long as Identity Impersonate = True is set.不是挖掘旧线程,但只要设置了 Identity Impersonate = True,这个函数就应该可以工作。 Here's some stuff being worked on.这里有一些正在处理的东西。

GitHub Doc GitHub 文档

Step-1 Open appsettings file add Integrated Security=true; 步骤1打开appsettings文件,添加Integrated Security = true; shown below 如下所示

{ "ConnectionStrings": { "MatcoDashboard": "server=machinename\\MSQL2008R2; database=databaename ;Integrated Security=true; " }, {“ ConnectionStrings”:{“ MatcoDashboard”:“服务器=计算机名\\ MSQL2008R2;数据库=数据库名称;集成安全性= true; ”},

Step -2 Copy your application pool name IIS APPPOOL\\matco 步骤-2 复制您的应用程序池名称IIS APPPOOL \\ matco

your application pool name = IIS APPPOOL\\matco 您的应用程序池名称= IIS APPPOOL \\ matco

Step -3 Go to Sql Server management studio create new user "IIS APPPOOL\\matco" with windows authentication and then map with database show below image details steps 步骤-3转到Sql Server Management Studio,使用Windows身份验证创建新用户“ IIS APPPOOL \\ matco” ,然后使用数据库映射显示以下图像详细信息步骤

step-1 create new user 步骤1 创建新用户

step-2 create new user with name IIS APPPOOL\\matco 步骤2 创建名为IIS APPPOOL \\ matco的新用户

step-3 User Mapping with Database 步骤3: 使用数据库进行用户映射

Go to IIS brows your page 转到IIS浏览您的页面

I'll add my answer because this is how I fixed this issue.我将添加我的答案,因为这是我解决此问题的方式。
The reason a "$"-sign is added to the login name/user must have something to do with the IIS that the application is being hosted on.将“$”符号添加到登录名/用户的原因必须与托管应用程序的 IIS 有关。

I'm not an expert on any of this, so I can't really go in-depth, but I've added the IIS user to the Logins and then it works.我不是这方面的专家,所以我不能真正深入,但我已经将 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  

You have to change 'name' to your IIS hosted application name.您必须将“名称”更改为您的 IIS 托管应用程序名称。 So for example if you app/site's name in ISS is "My-Backend-App" you should do:因此,例如,如果您在 ISS 中的应用程序/站点名称是“My-Backend-App”,您应该执行以下操作:

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

So all the names should be "My-Backend-App".所以所有的名字都应该是“My-Backend-App”。

When adding this user to the logins, my backend application could access & create the DB, create tables, access data etc...将此用户添加到登录时,我的后端应用程序可以访问和创建数据库、创建表、访问数据等...

SIDENOTE: I've used the Windows Event logger to find out this was my issue.旁注:我使用 Windows 事件记录器发现这是我的问题。 My application just crashed, said a "500.30" error but no real information given.我的应用程序刚刚崩溃,显示“500.30”错误,但没有给出真实信息。

You can access the "Event Viewer" application from Windows Search.您可以从 Windows 搜索访问“事件查看器”应用程序。 Then you can go to "Applications" and there are all application errors/crashes that occured on your machine, and in this case also the reason why.然后您可以转到“应用程序”,您的机器上发生了所有应用程序错误/崩溃,在这种情况下也是原因。 It said it couldn't find user "myUser$" while trying to login to SQL, but the Windows Authentication user was "myUser".它说在尝试登录 SQL 时找不到用户“myUser$”,但 Windows 身份验证用户是“myUser”。 So for some reason it added a "$"-sign and couldn't log in. My fix above fixes this issue and you can login etc.所以出于某种原因,它添加了一个“$”符号并且无法登录。我上面的修复解决了这个问题,你可以登录等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM