Инструменты пользователя

Инструменты сайта


iis-backchannel-logout

Галиев Б.А 2020/07/27 10:06

Реализация функциональной возможности Single Sign Out

Система «ЕСИ» реализует метод backchannel-logout для уведомления доверенных систем (Relying Parties) о выходе пользователя из учетной записи.

Уведомление происходит путем HTTP запроса на адрес backchannel_logout_uri, который заполняется при регистрации доверенной системы в ЕСИ.

При выходе пользователя формируется JWT токен, который содержит набор объектов Claim пользователя.

Пример полезной нагрузки JWT токена

{
  "nbf": 1595844077,
  "exp": 1595844377,
  "iss": "https://localhost:7001",
  "sub": "1000000",
  "aud": "mvc-client",
  "iat": 1595844077,
  "jti": "D5D482E197A188EC89B640DDA0AB0961",
  "sid": "6BC6B6F445B4CE79AAAC84F7461A0036",
  "events": {
    "http://schemas.openid.net/event/backchannel-logout": {}
  }
}

Реализация обработчика события Backchannel logout

Обработка события выхода Backchannel logout на стороне доверенной системы (Relying party) состоит из следующих этапов:

  1. Валидация JWT токена (параметры публичного ключа ЕСИ находятcя в discovery-document).
  2. Инвалидация сессионной cookie.

При инвалидации сессионной cookie используются два значения из JWT токена:

  1. sub - идентификатор пользователя ЕСИ
  2. sid - сессия пользователя ЕСИ

Пример:

      [HttpPost]
      [AllowAnonymous]
      public async Task<IActionResult> Index(string logout_token)
      {
        //Добавьте обработчики исключений
        //Валидация токена
        var user = await ValidateLogoutToken(logout_token);
        var sub = user.FindFirst("sub")?.Value;
        var sid = user.FindFirst("sid")?.Value;
        //Добавление sub sid для инвалидации сессии пользователя в Relying Party
        LogoutSessions.Add(sub, sid);
        return Ok();
      }

LogoutSessions это тестовый класс который содержит пару sub, sid в памяти.

Если пользователь через браузер осуществит вызов в Relying party, система должна проверить на наличие идентификатора и сессии пользователя в этой коллекции.

Если sub и sid пользователя есть в этой колекции то система должна уничтожить cookie тем самым совершив logout на стороне Relying party

Пример инвалидации сессионной cookie на Asp.Net Core 3

  public class CookieEventHandler : CookieAuthenticationEvents
  {
    public CookieEventHandler(LogoutSessionManager logoutSessions)
    {
      LogoutSessions = logoutSessions;
    }
    
    public LogoutSessionManager LogoutSessions { get; }
    
    public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
    {
      if (context.Principal.Identity.IsAuthenticated)
      {
        var sub = context.Principal.FindFirst("sub")?.Value;
        var sid = context.Principal.FindFirst("sid")?.Value;
        
        if (LogoutSessions.IsLoggedOut(sub, sid))
        {
          context.RejectPrincipal();
          await context.HttpContext.SignOutAsync();
          // todo: if we have a refresh token, it should be revoked here.
        }
      }
    }
  }
iis-backchannel-logout.txt · Последние изменения: 2020/09/16 12:21 — admin1