为什么创建包含认证用户会导致登录错误?
Why does creating contained authentication user cause login error?
在我的 SQL Server Express 2014 部分包含的数据库中创建一个包含的用户,在对现有打开的连接执行查询时导致异常。
这里是 SQL 打开包含的数据库身份验证并创建数据库:
EXEC sp_configure 'contained database authentication', 1
RECONFIGURE
GO
CREATE DATABASE TestContainedUserAuth CONTAINMENT = PARTIAL;
GO
USE TestContainedUserAuth;
GO
CREATE USER TestCreatorUser WITH PASSWORD='Test1234';
GO
ALTER ROLE db_owner ADD MEMBER TestCreatorUser;
GO
CREATE TABLE [dbo].[TestTable](
[TestTableID] [int] NOT NULL
) ON [PRIMARY]
GO
这是执行查询的 .Net 4.6.1 代码(请创建一个控制台项目并将其粘贴到 Program.cs,当然还要更改服务器和实例名称以匹配您的名称):
using System.Data.SqlClient;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
while (true)
{
using (var connection = new SqlConnection("Integrated Security=False;Data Source=localhost\SQLEXPRESS;Initial Catalog=TestContainedUserAuth;User ID=TestCreatorUser;Password=Test1234"))
{
connection.Open();
using (var cmd = new SqlCommand(@"SELECT * FROM TestTable", connection))
{
cmd.ExecuteNonQuery();
}
}
}
}
}
}
现在,在 运行使 C# 程序循环执行此查询后,运行 来自 SQL Management Studio(顺便说一句,我们完全意识到安全风险与包含的数据库和包含的数据库中的 dbo 用户相关联):
IF EXISTS(SELECT * FROM sys.database_principals WHERE name = N'MyNewUser') DROP USER MyNewUser;
GO
CREATE USER MyNewUser WITH PASSWORD=N'Abcd1234';
GO
在 SQL Management Studio 中执行 CREATE USER MyNewUser
(执行成功)后,我在 C# 程序中遇到此异常:
An unhandled exception of type 'System.Data.SqlClient.SqlException'
occurred in System.Data.dll
Additional information: Login failed for user
'S-1-9-3-1497860641-1239606672-4234875017-3655542527'.
A severe error occurred on the current command. The results, if any,
should be discarded.
如果我修改代码以保留对连接的引用并且不打开和关闭每个查询的连接,我不会得到异常。因此,当 ExecuteNonQuery 在从池中获取连接后尝试重新登录连接时,似乎发生了异常,但我不确定。
此外,如果关闭池(Pooling=False
在连接字符串中),则不会发生异常。
最后,在一个连接上出现一次此错误后,似乎现有的池连接是 "healed",并且从那时起对现有连接执行的查询成功,直到执行另一个 'CREATE USER'。
保持对永久打开连接的引用或关闭池都不是解决此错误的实用方法。任何帮助将不胜感激。
我认为你是对的。它使用池中的旧连接。
是否可以接受的解决方案是清除该连接的应用程序池?
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool.aspx
感谢您的建议。我们决定不使用遏制。使用非包含数据库和非包含SQL登录认证时不会出现该问题。
在我的 SQL Server Express 2014 部分包含的数据库中创建一个包含的用户,在对现有打开的连接执行查询时导致异常。
这里是 SQL 打开包含的数据库身份验证并创建数据库:
EXEC sp_configure 'contained database authentication', 1
RECONFIGURE
GO
CREATE DATABASE TestContainedUserAuth CONTAINMENT = PARTIAL;
GO
USE TestContainedUserAuth;
GO
CREATE USER TestCreatorUser WITH PASSWORD='Test1234';
GO
ALTER ROLE db_owner ADD MEMBER TestCreatorUser;
GO
CREATE TABLE [dbo].[TestTable](
[TestTableID] [int] NOT NULL
) ON [PRIMARY]
GO
这是执行查询的 .Net 4.6.1 代码(请创建一个控制台项目并将其粘贴到 Program.cs,当然还要更改服务器和实例名称以匹配您的名称):
using System.Data.SqlClient;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
while (true)
{
using (var connection = new SqlConnection("Integrated Security=False;Data Source=localhost\SQLEXPRESS;Initial Catalog=TestContainedUserAuth;User ID=TestCreatorUser;Password=Test1234"))
{
connection.Open();
using (var cmd = new SqlCommand(@"SELECT * FROM TestTable", connection))
{
cmd.ExecuteNonQuery();
}
}
}
}
}
}
现在,在 运行使 C# 程序循环执行此查询后,运行 来自 SQL Management Studio(顺便说一句,我们完全意识到安全风险与包含的数据库和包含的数据库中的 dbo 用户相关联):
IF EXISTS(SELECT * FROM sys.database_principals WHERE name = N'MyNewUser') DROP USER MyNewUser;
GO
CREATE USER MyNewUser WITH PASSWORD=N'Abcd1234';
GO
在 SQL Management Studio 中执行 CREATE USER MyNewUser
(执行成功)后,我在 C# 程序中遇到此异常:
An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: Login failed for user 'S-1-9-3-1497860641-1239606672-4234875017-3655542527'.
A severe error occurred on the current command. The results, if any, should be discarded.
如果我修改代码以保留对连接的引用并且不打开和关闭每个查询的连接,我不会得到异常。因此,当 ExecuteNonQuery 在从池中获取连接后尝试重新登录连接时,似乎发生了异常,但我不确定。
此外,如果关闭池(Pooling=False
在连接字符串中),则不会发生异常。
最后,在一个连接上出现一次此错误后,似乎现有的池连接是 "healed",并且从那时起对现有连接执行的查询成功,直到执行另一个 'CREATE USER'。
保持对永久打开连接的引用或关闭池都不是解决此错误的实用方法。任何帮助将不胜感激。
我认为你是对的。它使用池中的旧连接。
是否可以接受的解决方案是清除该连接的应用程序池?
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool.aspx
感谢您的建议。我们决定不使用遏制。使用非包含数据库和非包含SQL登录认证时不会出现该问题。