Pull to refresh

Использование ЕСИА в .NET

При работе над проектом заказчику потребовалась связь с ЕСИА для получения различных данных. Проект представляет собой веб-приложение на ASP.NET MVC 5.


Соответственно были изучены методические рекомендации, произведено тестовое подключение к ЕСИА. Вообще, методические рекомендации не похожи на техническую документацию, но это все что есть по использованию ЕСИА в приложениях. Разобраться вполне можно, ничего сложного нет, хотя немного не привычно.


Поиск в интернете готовых решений для .NET не дал, кроме платных библиотек. Было ясно, что реализовать доступ к ЕСИА собственными силами вполне возможно, таким образом платные решения не рассматривались.


Проект к тому времени был практически завершен и проходил опытную эксплуатацию, так что работа с ЕСИА должна быть аккуратно интегрирована и без последствий. Мне не хотелось много менять в проекте – хотелось использовать реализованный функционал, благо архитектура позволяла.


Приложение требовало для работы авторизации и использует для этого ASP.NET Identity 2. ЕСИА тоже требует авторизации, поэтому хотелось встроить эту авторизацию в ASP.NET Identity, аналогично авторизации Google, Facebook, Twitter. Это избавило бы меня от лишнего функционала и легко легло бы в приложение. ЕСИА OAuth2 как раз позволяет это сделать (SAML не рассматривался, так как нужен доступ к REST).


Теперь ясно что делать. В итоге был реализован интерфейс для работы с ЕСИА по OAuth2 и получения данных из REST сервисов. Получение данных из REST сервисов реализовано через соответствующие методы, которые возвращают готовые классы (не нужно ничего парсить). Дополнительно было разработано «OWIN middleware» для интеграции авторизации через ЕСИА в ASP.NET Identity. Все это было выделено в отдельные сборки, которые можно использовать и в других приложениях.


В итоге, сейчас реализован процесс авторизации через ЕСИА в приложении, а также получение необходимых данных в любом месте в рамках сессии.


Получилось вроде бы неплохо и хотелось бы поделиться наработками с сообществом. Так появилась библиотека EsiaNET (https://github.com/xeltan/EsiaNET), доступная в Nuget.


Библиотека состоит из двух сборок:


  • EsiaNET – клиент ЕСИА для использования в приложениях и получения данных. Предоставляет класс EsiaClient для работы с ЕСИА;
  • EsiaNET.Identity – OWIN middleware для интеграции в ASP.NET Identity, использует EsiaNET.

Рассмотрим простой пример использования библиотеки с интеграцией в ASP.NET Identity


Установка и использование


Для установки необходимо ввести следующую команду в Package Manager Console:


PM> Install-Package EsiaNET.Identity


Далее нужно разрешить использовать в ASP.NET Identity внешнюю авторизацию через ЕСИА в OWIN startup class


app.UseEsiaAuthentication(new EsiaAuthenticationOptions(Esia.GetOptions())
{
    VerifyTokenSignature = true,    // Будем проверять подпись маркера доступа
    Provider = new EsiaAuthenticationProvider
    {
        OnAuthenticated = context =>    // Сохраним после авторизации маркер доступа в сессии для будущего использования в приложении
        {   // или достанем данные прямо здесь
            HttpContext.Current.Session["esiaToken"] = context.Token;

            return Task.FromResult<object>(null);
        }
    }
});

Здесь Esia.GetOptions() возвращает параметры ЕСИА, которые передаются в EsiaClient. Эти же параметры должны использоваться далее в приложении при работе с ЕСИА через EsiaClient.


public class Esia
{
    public static EsiaOptions GetOptions()
    {
        return new EsiaOptions
        {
            ClientId = "CLIENT_ID",    // Ваш идентификатор системы-клиента
            RedirectUri = EsiaConsts.EsiaAuthTestUrl,   // Адрес перенаправления на страницу предоставления прав доступа в ЕСИА - либо тестовый, либо рабочий
            TokenUri = EsiaConsts.EsiaTokenTestUrl,     // https-адрес ЕСИА для получения маркера доступа - либо тестовый, либо рабочий
            RestUri = EsiaConsts.EsiaRestTestUrl,       // Адрес REST-сервиса ЕСИА для получения данных - либо тестовый, либо рабочий
            Scope = "http://esia.gosuslugi.ru/usr_inf", // Область доступа, т.е. запрашиваемые права. Можно указать несколько через пробел

            // Провайдер для получения сертификата системы-клиента. Обязан вернуть сертификат. В данном примере сертификат ищется на локальной машине по серийному номеру
            SignProvider = EsiaOptions.CreateSignProvider(() =>
            {
                // Будем искать сертификат в личном хранилище на локальной машине
                X509Store storeMy = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                storeMy.Open(OpenFlags.OpenExistingOnly);
                X509Certificate2Collection certColl = storeMy.Certificates.Find(X509FindType.FindBySerialNumber, WebConfigurationManager.AppSettings["AppCertSerial"], false);

                storeMy.Close();

                return certColl[0];
            },
                // Action должен вернуть сертификат ЕСИА тестовый или рабочий. В данном примере ищем сертификат по его пути, указанном в конфигурационном файле
                () => new X509Certificate2(WebConfigurationManager.AppSettings["EsiaCertFile"]))
        };
    }
}

Далее в приложении можно использовать EsiaNET.EsiaClient для работы с данными ЕСИА. Например


// Создаем ЕСИА клиента с маркером доступа для получения данных
var esiaClient = new EsiaClient(Esia.GetOptions(), (EsiaToken)Session["esiaToken"]);

// Получим данные о пользователе
var personInfo = await esiaClient.GetPersonInfoAsync();
// Пользователь не подтвержден - выводим ошибку
if ( !personInfo.Trusted ) throw new Exception("Данные не подтверждены");

// Получаем контакты
var contacts = await esiaClient.GetPersonContactsAsync();

// Получаем документы пользователя
var docs = await esiaClient.GetPersonDocsAsync();

// Получаем адреса пользователя
var addrs = await esiaClient.GetPersonAddrsAsync();

Вообще, EsiaNET.EsiaClient можно использовать отдельно от EsiaNET.Identity, но тогда процесс авторизации и получения маркера доступа полностью ляжет на приложение.


На странице библиотеки на https://github.com/xeltan/EsiaNET доступна документация по использованию.


Надеюсь будет полезно.

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.
Change theme settings