Почему я не могу прочитать таблицу базы данных SQL Server, используя группу Windows для проверки подлинности Windows?

Моя цель - предоставить любого пользователя, который является членом группы Windows TestDbAccess доступ для чтения к [Test].[dbo].[Persons] через прикладную программу C#.

проблема

  • Когда я захожу на компьютер C2.foo.gov используя domain admin account и выполнить программу (см. ниже), программа считывает базу данных и отображает одну запись в сетке, как и ожидалось (поэтому я знаю, что код в порядке).

  • Когда я захожу на компьютер C2.foo.gov с использованием ssmith@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 журнал ошибок)

Почему я не могу прочитать свою таблицу базы данных SQL Server, используя группу Windows для проверки подлинности Windows?

Вот что у меня есть:

  • Все компьютеры, пользователи и группы являются членами домена foo.gov.

  • Домен находится в неподключенном анклаве. Все брандмауэры отключены.

  • 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, Тип Security

  • ssmith@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>

Класс DatabaseAccess

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);
            }
        }
    }
}

1 ответ

Как оказалось, мой код, как показано, работает. После того, как я опубликовал свой вопрос 7/16, мне нужно было установить обновления Windows на компьютер C1. Я так и сделал, перезапустил С1, потом пошел домой. Когда я вернулся на следующее утро, я решил повторить запуск своей программы на компьютере C2, используя логин ssmith@foo.gov. Это сработало. Итак, я должен предположить, что перезагрузка компьютера C1 и / или выделение достаточного времени для изменений в Active Directory (добавление группы TestDbAccess в AD и SQL Server) для распространения сделали свое дело.

Другие вопросы по тегам