Разработка
26
Фев
2

Подключение к SQL серверу из плагинов

Предположим, у Вас есть потребность обратится к данным не CRM’ной базы данных SQL Server’а из плагина… Это может быть сделно, например, в целях интеграции с другой системой или обращение к общему хранилищу данных и т.д.

Проблема, с которой Вы столкнетесь, состоит в том, что системная учетная запись, из под которой плагин выполняется, не имеет доступ к SQL Server’у и базам данных. В Microsoft Dynamics CRM все плагины выполняются под системной учетной записью NT AUTHORITY\NETWORK SERVICE.

Поэтому у Вас есть два пути:

  1. Использовать интегрированную аутентификацию (т.е. c использованием доменной учетной записи)
    • При этом SQL запрс будет выполнятся под учетной записью NT AUTHORITY\NETWORK SERVICE у которой, как уже говорилось нет необходимых прав (на подключение к Вашим базам данных). Поэтому Вы можете либо выдать ей необходимы права, либо заставить код выполнятся под конкретной учеткой (зарегистрированной в SQL сервере). Например, Вы может создать в SQL учетку основанную на учетной записи из Active Directory и соответствующую тому пользователю, который будет запускать плагин (если таких пользователей несколько, то и учеток в SQL Server’е необходимо создать несколько). Затем выдать права созданной учетки на выполнение необходимых действий (с Вашими базами данных). А чтобы выполнить SQL команды от лица конкретного SQL пользователя , Вы должны использоватьT-SQL конструкцию Execute AS при написании SQL запроса. Все это имеет смысл, например, если у Вас есть какие-нибудь хранимый процедуры на SQL сервере, которые необходимо запускать в контексте конкретных пользователей (точнее конкретный учетных записей в SQL сервере);
    • Далее необходимо учетной записи NT AUTHORITY\NETWORK SERVICE (из под которой выполняется плагин) предоставить разрешения для подключения к SQL серверу;
    • При интегрированной аутентификации строка подключения к SQL серверу в C#-коде будет выглядеть так:
      Data Source=mySQLServer;Initial Catalog=myDataBaseName;Integrated Security=SSPI;


  1. Аутентификация SQL Server’а
    • Для этого необходимо создать скульную учетку (через которую будете получать доступ к БД) и выдать ей необходимые права;
    • Разрешить SQL серверу использовать собственную аутентификацию (если она у Вас не разрешена). Делается это в свойствах SQL сервера (щелчок правой кнопкой мыши по руту в Msnsgament Studio – properties — security). И не забудьте после этого рестартнуть SQL сервер;
    • В этом случаи строка подключения к SQL серверу в C#-коде будет такой:
      Data Source=mySQLServer;Initial Catalog=myDataBaseName;User Id=myUsername;Password=myPassword;Integrated Security=false;

      Учтите, что т.к. придется хранить логин и пароль в чистом виде. То имеет смысл поместить его Secure Configuration, ну или захардкодит 🙂


Рассмотрим небольшой пример…

Создайте в SQL сервере учетную запись, сответствующую тому пользователю, из под которого будет выполнтся плагин. В данным примере, SQL запрос выполняется под доменной учеткой юзвера запустившего плагин, поэтому если система не найдет такой учетки, то свалится с ошибкой. При этом ничего не мешает Вам переписать код так, чтобы он выполнялся под одной конкретной учеткой (как виндовой, так и скульной) если у Вас нет необходимости выполнять SQL запрос в контексте конкретного юзвера;

  • Т.к. я планирую использовать интегрированную аутентификацию, то сначала необходимо выдать различные права для учтеки NT AUTHORITY\NETWORK SERVICE из под которой выполняется плагин (права на олицетворение в частности). И т.к. это просто пример, то я выдам ей права сисадмина 🙂
  • SQL запрос будет выполнятся под конкретным SQL-пользователем (учетная запись которого создана на основе учетки из Active Directory). Но, т.к. я работаю из под админа устанавливающего SQL сервер, то его учетка уже заведена 🙂 Но Вам необходимо ее создать (если она уже не создана) 🙂
  • Создайте плагин и повесьте на него такой код:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Crm.Sdk;
    using Microsoft.Crm.SdkTypeProxy;
    using Microsoft.Crm.Sdk.Query;
    using System.Data.SqlClient;
    
    public class AccessDatabase : IPlugin
    {
        string m_connectionString;
    
        // Передаем строку подключения (заданную во время регистрации плагина) к конструктору плагина.
        public AccessDatabase(string config, string secureConfig)
        {
            m_connectionString = config;
        }
    
        // При выполнении плагина...
        public void Execute(IPluginExecutionContext context)
        {
            // Шаг 1. Получаем доменное имя пользователя запустившего плагин
            ICrmService crmService = context.CreateCrmService(false);
            systemuser callingUser = (systemuser)crmService.Retrieve(
                EntityName.systemuser.ToString(),
                context.UserId,
                new ColumnSet(new string[] { "domainname" })
            );
    
            // Шаг 2. Подключаемся к SQL серверу используя строку подключения
            using (SqlConnection conn = new SqlConnection(m_connectionString))
            {
                conn.Open();
                SqlCommand comm = conn.CreateCommand();
    
                // Шаг 3. Начинаем SQL олицетворение
                comm.CommandText = @"Execute as Login='" + callingUser.domainname + "'; ";
                
                // Шаг 4. Выполняем необходимые SQL команды
                comm.CommandText += "SELECT SUSER_NAME(); ";
                
                // Шаг 5. Возвращаем контекст обратно к Network Service
                comm.CommandText += "revert;";
    
                comm.CommandType = System.Data.CommandType.Text;
    
                // Выводим в сообщении имя пользователя выполневшего SQL запрос (и которого мы выбрали с помощью оператора SELECT)
                throw new InvalidPluginExecutionException(comm.ExecuteScalar().ToString());
            }
        }
    }
    

    Данный код делает следующее:

    • Получает строку подключения из Unsecure Configuration (ее мы зададим позже при регистрации плагина);
    • Создает экземпляр CRM Service и отправляет ему запрос для извлечения доменной учетки юзвера, запустившего плагин;
    • Используя строку подключения (из Unsecure Configuration) соединяемся с SQL сервером;
    • Выполняем SQL команду под доменной учеткой, которую мы вытащили из записи пользователя, запустившего плагин;
    • В данном примере, SQL запрос просто вернет доменную учтку пользователя из под которой этот SQL запрос выполнялся.
  • Зарегистрируйте плагин на любое событии. При этом в Unsecure Configuration поместите строку такого вида:
    Data Source=mySQLServer;Initial Catalog=myDataBaseName;Integrated Security=SSPI;

    Только подставьте в нее Ваши имя SQL сервера и базы данных;

  • Вызовите событие в CRM.



Комментарии (2)
  • Aleks 26.02.2010

    Я немного не понял. Мне нужно из плагина передать данные на другой сервер. В connectionString я указываю параметры, куда буду передавать. В Unsecure Configuration — здесь параметры, откуда буду передавать. Так. При срабатывании возникает ошибка login failed for user ‘СС\dynamics’.

  • Aleks 26.02.2010

    Все спасибо разобрался сам.

*

code