【发布时间】:2018-07-16 16:32:27
【问题描述】:
我的目标是通过 C# 应用程序为 Windows 组 TestDbAccess 的成员提供对 [Test].[dbo].[Persons] 的读取访问权限。
问题
当我使用
domain admin account登录计算机C2.foo.gov并执行程序(见下文)时,程序读取数据库并按预期在网格中显示一条记录(所以我知道代码是好的)。当我使用
ssmith@foo.gov帐户登录计算机C2.foo.gov并执行程序时,我收到一个SQL Server 错误Login failed for user 'foo\ssmith'. Reason: Could not find a login matching the name provided. [CLIENT: xxx.xx.xx.xxx]。 (错误在SQL Server错误日志中)
为什么我无法使用 Windows 组读取我的 SQL Server 数据库表以进行 Windows 身份验证?
这是我所拥有的:
所有计算机、用户和组都是 foo.gov 域的成员
域位于未连接的 enclave 中。所有防火墙均已关闭。
SQL Server(默认实例)安装在计算机
C1.foo.gov上。有数据库Test和表[dbo].[persons]。[Test].[dbo].[Persons]有一条记录。该数据库是使用具有Server Rolespublic和sysadmin的域管理员帐户创建的。具有User Mapping的db_owner和public到Test数据库。SQL Server(默认实例)具有安全登录 foo\TestDbAccess。
Server Role是public。User mapping是db_datareader和public用于数据库Test,user=foo\TestDbAccess,default schema=dbo。状态:Permission to connect to database engine=Grant。Login=Enabled用户
ssmith@foo.gov存在于Active Directory Users and Computers中TestDbAccess组存在于Active Directory Users and Computers中。范围是Global。类型是Securityssmith@foo.gov是TestDbAccess的成员
代码如下。
app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="DbConnectionString"
connectionString="Data Source=C1;Initial Catalog=Test;Integrated Security=True;Trusted_Connection=True;Connection Timeout=10"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
数据库访问类
using System.Data;
using System.Data.SqlClient;
namespace DbAccessWindowsGroups
{
public static class DatabaseAccess
{
internal static DataTable GetData()
{
DataTable dataTable_TableList = new DataTable
{
TableName = "test"
};
try
{
using (SqlConnection sqlConnection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DbConnectionString"].ToString()))
{
using (SqlCommand sqlCommand = new SqlCommand())
{
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandType = CommandType.Text;
sqlCommand.CommandText = "SELECT TOP 1000 [Test].[dbo].[Persons].[iuid], [Test].[dbo].[Persons].[Name] FROM [Test].[dbo].[Persons]";
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
dataTable_TableList.Load(sqlDataReader);
}
}
}
catch
{
throw;
}
return dataTable_TableList;
}
}
}
Form1 类
using System;
using System.Data;
using System.Windows.Forms;
namespace DbAccessWindowsGroups
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
try
{
BindingSource bindingSource = new BindingSource();
dataGridView1.DataSource = null;
DataTable dataTable = DatabaseAccess.GetData();
bindingSource.DataSource = dataTable;
dataGridView1.DataSource = bindingSource;
}
catch (Exception ex)
{
Program._DisplayMessage("Error", ex, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
【问题讨论】:
-
您的详细信息非常详尽。谢谢!请确认 ssmith 在域 FOO 中,并且作为登录名启用,然后该 ssmith 在组 foo\testdbaccess 中。该错误表明用户无权访问。那么当你在 master 中运行时你会看到什么(不要发布 SID):“select * from sys.syslogins where [loginname] = 'foo\testdbaccess';”然后切换到测试数据库,让我知道您看到的“select * from sys.database_principals where [name] = 'foo\testdbaccess';”这应该可以帮助我们解决这个问题。
-
16 小时有何不同。在 7/16 发布我的问题后,我需要在 C1 上安装 Windows 更新。我这样做了,重新启动了 C1,然后回家了。当我今天早上回来时,我开始收集您问题的答案,但随后决定使用
ssmith@foo.gov登录在计算机 C2 上重新运行我的程序。有效。所以,我必须假设重新启动计算机 C1 和/或让我的Active Directory更改有足够的时间(将组TestDbAccess添加到A.D.和SQL Server)来传播成功了吗?想法? -
有道理。请将答案发布为答案并将其标记为已解决。
标签: c# sql-server winforms active-directory windows-authentication