При попытке интеграции внешних приложений на языке C# с платформой 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда добавление ссылки на веб-сервис или обращение к интерфейсу OData зацикливается на окне ввода логина и пароля. Visual Studio может выдавать предупреждение «The server needs to authenticate your request. Your credentials will be sent to the server in clear text», после чего многократный ввод корректных учетных данных пользователя 1С не дает результата.
Разберем детально, почему возникает конфликт аутентификации между веб-сервером IIS и платформой 1С, как правильно настроить публикацию базы данных, файл default.vrd и как корректно передавать учетные данные из кода C#.
Выясним причину, почему стандартная форма запроса учетных данных появляется снова и снова. Здесь работают два ключевых механизма:
wsisapi.dll).Проанализируем конфигурацию веб-сервера. Чтобы проверка прав выполнялась непосредственно внутри 1С, веб-сервер должен пропускать входящий трафик без предварительной проверки системных пользователей Windows.
Включено.Отключено.В этом случае запросы беспрепятственно доходят до платформы 1С, и именно она будет запрашивать и проверять учетные данные пользователя информационной базы.
Рассмотрим альтернативный вариант, когда для веб-сервисов или OData требуется полностью отключить диалог авторизации со стороны клиентов, жестко зафиксировав пользователя базы данных в настройках публикации. Для этого используется файл default.vrd, расположенный в каталоге публикации.
В атрибуте ib можно напрямую указать учетную запись 1С:
<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
base="/Demo1C"
ib="File="D:\Documents\InfoBase5";usr=WebUser;pwd=12345"
enableStandardOData="true">
<httpServices publishByDefault="false"/>
<ws>
<point name="WebAbit" alias="ws1.1cws" enable="true"/>
</ws>
</point>
Важное требование к файлу: сохранять файл default.vrd необходимо строго в кодировке UTF-8 (без сигнатуры BOM). Если сохранить файл в ANSI при наличии кириллических символов (например, в логине пользователя), платформа 1С вернет фатальную ошибку: Ошибка разбора XML: Input is not proper UTF-8.
Для исключения проблем с кодировками рекомендуется заводить специального служебного пользователя 1С с логином и паролем только на латинице (например, WebUser).
Рассмотрим, как правильно инициализировать клиент WCF на стороне C#, если сервис требует авторизации. Для предотвращения двойного запроса (когда первый запрос уходит анонимно, возвращает ошибку 401 Unauthorized и только затем шлет заголовок) настроим предварительную авторизацию и передачу заголовка Basic Auth в кодировке UTF-8.
Посмотрим на пример конфигурации клиента программным способом:
var binding = new BasicHttpBinding();
binding.SendTimeout = TimeSpan.FromSeconds(25);
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
var address = new EndpointAddress("http://localhost/Demo1C/ws/WebAbit.1cws");
using (var client = new WebAbitPortTypeClient(binding, address))
{
client.ClientCredentials.UserName.UserName = "WebUser";
client.ClientCredentials.UserName.Password = "12345";
using (var scope = new OperationContextScope(client.InnerChannel))
{
var httpRequestProperty = new HttpRequestMessageProperty();
// Формируем заголовок Authorization вручную в UTF-8 для надежности
string authInfo = client.ClientCredentials.UserName.UserName + ":" + client.ClientCredentials.UserName.Password;
string authHeader = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(authInfo));
httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = authHeader;
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
// Вызов метода веб-сервиса 1С
var result = client.GetSomeData();
}
}
Разберем по шагам работу со стандартным интерфейсом OData 1С, когда в Visual Studio создается ссылка через Add Service Reference на адрес вида http://localhost/Demo1C/odata/standard.odata/.
NetworkCredential:
var uriString = @"http://localhost/Demo1C/odata/standard.odata/";
var context = new StandardODATA.EnterpriseV8(new Uri(uriString));
context.Credentials = new NetworkCredential("WebUser", "12345");
// При необходимости отправки заголовка в UTF-8 для OData-клиента:
context.SendingRequest2 += (sender, e) =>
{
string auth = Convert.ToBase64String(Encoding.UTF8.GetBytes("WebUser:12345"));
e.RequestMessage.SetHeader("Authorization", "Basic " + auth);
};
Обратите внимание на получение данных через LINQ. Вместо явного вызова метода CreateQuery предпочтительнее обращаться напрямую к сформированным сущностям контекста:
var result = (from item in context.Catalog_ТипыДокументов
select item).Take(10).ToList();
foreach (var row in result)
{
string name = row.Description;
}
При соблюдении этих настроек — анонимный доступ на уровне IIS, корректная UTF-8 структура файла default.vrd и явная передача заголовков авторизации из кода — подключение из C# к веб-сервисам и REST-интерфейсу 1С выполняется стабильно и без зацикленных окон проверки подлинности.