Аутентификация в SharePoint через .Net, но через Node.js
Вступление
Порой обожаю технологические эксперименты и реализацию безумных, как бы ни казалось, идей. Часто ловишь себя на мысли "А почему бы не сделать [вот так-то, как никто еще не делал]?", а потом понимаешь, что на одном дыхании и реализовал задуманное с восклицанием "Ничего себе! Работает! O_o". Примерно таким образом явились свету некоторые из моих Open Source проектов.
Вот таким образом не так давно пришлось покопаться с Edge.js. Edge.js - это библиотека, которая позволяет запускать CLR языки, такие как C# .Net из Node.js и, наоборот, Node.js из .Net.
Довольно давно хотелось синхронизировать sp-cmd-deploy
(.Net модуль для получения CSOM контекста) c node-sp-auth-config
(Node.js модуль для настроек аутентификации). Обе библиотеки разделяют общие подходы. И было бы неплохо, чтобы для Node.js и .Net в части настроек был общий слой.
Обсуждая эту идею кто-то сказал "А почему бы не переиспользовать node-sp-auth-config
в наших .Net приложениях как есть?". Хм... сказано, сделано!
SPAuthN
Собсвтенно, SPAuthN
- результат эксперимента и немного "Франкенштейн". SPAuthN является .Net библиотекой, устанавливаемой из NuGet'ов. Библиотека является оберткой для node-sp-auth и node-sp-auth-config. Данный монст позволяет аутентифицироваться в SharePoint с разнообразной поддержкой сценарией аутентификации и консольным мастером подключения и слоем конфигурационных файлов идентичных нашему Node.js стеку.
Предупреждение
Перед дальнейшим чтением, минутка внимания! Прежде всего это эксперимент направленный на решение очень узкой и специфичной задачи связки SharePoint, Node.js и .Net где нам нужно именно то, что нужно, а именно переиспользование практик Node.js в составе .Net приложений. Мы понимаем что и почему делаем и зачем. Использование самой же библиотеки может быть только целесообразно если штатных средств .Net не хватает для определенного аутентификационного сценария, но он есть и работает в node-sp-auth
.
Для кого эта библиотека?
Предже всего для Node.js разработчиков, плотно использующих node-sp-auth и node-sp-auth-config, кому нужно в рамках .Net приложения переиспользовать имеющиеся возможности.
Для гиков, кому интересны нестандартные подходы изящно решающие необычные задачи.
Для случаев, когда .Net приложение потенциально должно поддерживать массу различных сцениариев аутентификации.
И конечно же, нет никакого смысла использовать, если подходят штатные хелперы по аутентификации:
- context.Credentials = new SharePointOnlineCredentials("username", "securepass");
- context.Credentials = new NetworkCredential("username", "password", "domain");
- и другие.
Возможности
SPAuthN поддерживает аутентификацию с SharePoint Online, 2019б 2016, 2013. По сути дела, все в одном: Addin only разрешений, SAML, ADFS, NTLM, FBA, TMG и др.
Принцип работв
- Edge.js оборачивает запуск Node.js скриптов с мастерами настройки, аутентифицакии и утилит
- Edge.js предоставляет встроенную среду исполнения серверного JavaScript
- Часть исполнения передается на сторону JS, результат в виде аутентификационных заголовков возвращается назад в управляемый код
- Аутентификационные заголовки инжектятся в запросы уже на стороне .Net кода
Как использовать
Options options = SPAuth.GetAuth();
И это все, да, на самом деле так просто!
Теперь в объекте options.headers
находят я Cookie или Authorization заголовки, которые нужно подставить в запрос к SharePoint. Однако, таймауты сессий нужно контролировать в ручную или получать авторизацию перед запросами, а внутреннее кеширование следит за сроком жизни токенов.
Параметры аутентификации
node-sp-auth-config отвечает за интерактивный ввод стратегии и соответствующих параметров аутентификации:
По умолчанию, параметры подключения сохраняются в ./config/private.json
корневой директории подключения.
Метод GetAuth
проверяет наличие и содержимое ./config/private.json
и запрашивает недостающие параметры, либо продолжает работу, если все необходимое на месте.. Пароль хранится в зашифрованном виде и подлежит расшифровке только на той машине, где был создан.
Аргументы
Метод GetAuth
так же может получать строку с параметрами, переопределяющими общее поведение. Параметры можно посмотреть в коде - AuthConfigSettings.
Options options = SPAuth.GetAuth("--encryptPassword=false --configPath='./config/private.uat.json'");
Сценарии использования параметров
Определение пути до файла с параметрами подключения
--configPath='./config/private.prod.json'
Переключение между разными тенантами, учетными данными и окружением.
Шифрование пароля
--encryptPassword=false
По умолчанию, пароль шифруется, но иногда может потребоваться отключение данной возможности.
Блокировака записи файла параметров на диск
--saveConfigOnDisk=false
В случаях, когда требуется всегда запрашивать пользователя приложения о всех или части параметров. Например, можно иметь частично заполненный файл, где пароль всегда нужно подтверждать.
Принудительный запрос параметров
--forcePrompts=true
Переинициализация мастера ввода параметров.
Явная передача ауторизационных данных
--authOptions.siteUrl="http://sharepoint" --authOptions.username="user@contoso.com" --authOptions.password="p@ssw0rd" --saveConfigOnDisk=false
Примеры использования
WebRequest
ptions options = SPAuth.GetAuth("--configPath='./config/private.json'");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(options.SiteUrl + "/_api/web?$select=Title");
Request.ApplyAuth(request, options);
request.Method = "GET";
request.Accept = "application/json; odata=verbose";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NoContent)
{
using (Stream dataStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataStream))
{
string strResponse = reader.ReadToEnd();
dynamic results = JsonConvert.DeserializeObject(strResponse);
Console.WriteLine("REST | Web title is: {0}", results.d.Title);
}
}
}
}
CSOM
Options options = SPAuth.GetAuth("--configPath='./config/private.json'");
using (ClientContext clientContext = new ClientContext(options.SiteUrl))
{
Request.ApplyAuth<WebRequestEventArgs>(clientContext, options);
var web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
Console.WriteLine("CSOM | Web title is: {0}", web.Title);
}
Заключение
Пожалуйста, не поймите меня неправильно. Я прекрасно понимаю, что SPAuthN это узконаправленный продукт, но с другой стороны он демонстрир
Опубликовано: 19.11.2018
Автор: Андрей Кольтяков