IdP Proxy - инициировано SLO SP - PullRequest
0 голосов
/ 23 мая 2018

Я пытаюсь создать IdP-Proxy на основе решения SAML в компонентном пространстве.

До сих пор я мог обрабатывать единый вход следующим образом:

  1. Добавить метод SingleSignOnService, который получает запрос AUTHN от SP и инициируетSSO для партнера IdP (SP-initiated SSO).
  2. Добавьте AssertionConsumerService, который получает результат SSO, и флажок cheks IsInResponseTo.Основываясь на этом флаге, я определил, нахожусь ли я в SP-initiated SSO или в IdP-initiated SSO потоке, и соответствующим образом завершил поток.

Я пытаюсь обработать одиночный выход таким же образом, используяследующий пример потока: Single SAMLv2 Identity Provider Proxy Logout

Теоретически для выхода из системы, инициированного SP, мне необходимо добиться следующего: 1. Получить один запрос на выход из системы 2. Проверить, неответ 3. Определите IdP 4. Отправьте запрос Slo на IdP, определенный на шаге 3. 5. Ответьте на SLO, инициированный SP, указывая успешный выход из системы.

public async Task<IActionResult> SingleLogoutService()
{
    // Receive the single logout request or response.
    // If a request is received then single logout is being initiated by a partner service provider.
    // If a response is received then this is in response to single logout having been initiated by the identity provider.
    var sloResult = await _samlIdentityProvider.ReceiveSloAsync();

    if (sloResult.IsResponse)
    {     
    }
    else
    {
      // Figure out IdP Partner Name 
      var idpPartnerName = _configuration["IdPPartnerName"];

      // Send logout request to idp partner
      await _samlServiceProvider.InitiateSloAsync(idpPartnerName, sloResult.LogoutReason, sloResult.RelayState);

      // Respond to the SP-initiated SLO request indicating successful logout.
      await _samlIdentityProvider.SendSloAsync();
    }

    return new EmptyResult();
  }

Я могу уничтожитьсеанс в конце SP, но я не могу удалить сеанс IdP (я думаю, что

await _samlServiceProvider.InitiateSloAsync(idpPartnerName, sloResult.LogoutReason, sloResult.RelayState);

должен инициировать удаление сеанса IdP, что является третьим шагом в прикрепленномпроцесс прокси).

Что-то, чего мне не хватает, "по протоколу"?

Приложение (InitiateSloAsync метод):

public async Task InitiateSloAsync(string partnerName, string logoutReason, string relayState)
    {
      int num;
      if ((uint) num <= 5U)
        ;
      try
      {
        this.logger.LogDebug("Initiating SLO to the partner identity provider" + (string.IsNullOrEmpty(partnerName) ? "." : string.Format(" {0}.", (object) partnerName)), Array.Empty<object>());
        await this.LoadSamlStateAsync();
        this.LogSessionState();
        await this.GetLocalSpConfigurationAsync();
        if (this.SamlState.ServiceProviderSessionState.PendingResponseState != null)
          this.logger.LogDebug(string.Format("The pending SAML action {0} is being overridden.", (object) this.SamlState.ServiceProviderSessionState.PendingResponseState.Action), Array.Empty<object>());
        if (string.IsNullOrEmpty(partnerName) && this.SamlState.ServiceProviderSessionState.SsoSessions.Count == 1)
        {
          IEnumerator<SsoSessionState> enumerator = this.SamlState.ServiceProviderSessionState.SsoSessions.Values.GetEnumerator();
          enumerator.MoveNext();
          partnerName = enumerator.Current.PartnerName;
          enumerator = (IEnumerator<SsoSessionState>) null;
        }
        await this.GetPartnerIdpConfigurationAsync(partnerName);
        if (this.partnerIdentityProviderConfiguration.DisableOutboundLogout)
          throw new SamlProtocolException(string.Format("Logout to the partner identity provider {0} is disabled.", (object) partnerName));
        XmlElement xmlElement = await this.CreateLogoutRequestAsync(logoutReason);
        XmlElement logoutRequestElement = xmlElement;
        xmlElement = (XmlElement) null;
        await this.SendLogoutRequestAsync(logoutRequestElement, relayState);
        this.SamlState.ServiceProviderSessionState.SsoSessions.Remove(this.partnerIdentityProviderConfiguration.Name);
        SamlSubject.OnLogoutRequestSent(partnerName, logoutRequestElement, relayState);
        await this.SaveSamlStateAsync();
        this.LogSessionState();
        this.logger.LogDebug(string.Format("Initiation of SLO to the partner identity provider {0} has completed successfully.", (object) partnerName), Array.Empty<object>());
        logoutRequestElement = (XmlElement) null;
      }
      catch (Exception ex)
      {
        this.logger.LogError((EventId) 101, ex, string.Format("Initiation of SLO to the partner identity provider {0} has failed.", (object) partnerName), Array.Empty<object>());
        throw;
      }
    }

1 Ответ

0 голосов
/ 24 мая 2018

Согласно ответу ComponentSpace, указанному здесь: https://www.componentspace.com/Forums/8806/?Update=1#bm8813 проблема связана с не ожиданием ответа от IdP.

В соответствии с текущей реализацией InitiateSloAsync будет отправлять только запрос SLO в IdP, но не будет ждать ответа.

// Send logout request to idp partner
await _samlServiceProvider.InitiateSloAsync(idpPartnerName, sloResult.LogoutReason, sloResult.RelayState);

// Respond to the SP-initiated SLO request indicating successful logout.
await _samlIdentityProvider.SendSloAsync();

Процесс выглядит следующим образом:

  1. Получение запроса на выход из системы SP.
  2. Определение IdP.
  3. Отправка запроса на выход из IdP.
  4. Получение ответа на выход из IdP.
  5. Отправка ответа на выход для SP.

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

Когда вы действуете как IdP:

public async Task<IActionResult> SingleLogoutService()
{
  // Receive the single logout request or response.
  // If a request is received then single logout is being initiated by a partner service provider.
  // If a response is received then this is in response to single logout having been initiated by the identity provider.
  var sloResult = await _samlIdentityProvider.ReceiveSloAsync();

  if (sloResult.IsResponse)
  {   
  }
  else
  {
    // Figure out IdP Partner Name 
    var idpPartnerName = _configuration["IdPPartnerName"];

    // Send logout request to idp partner
    await _samlServiceProvider.InitiateSloAsync(idpPartnerName, sloResult.LogoutReason, sloResult.RelayState);
  }

  return new EmptyResult();
}

Когда вы действуете в качестве SP:

public async Task<IActionResult> SingleLogoutService()
{
  // Receive the single logout request or response.
  // If a request is received then single logout is being initiated by the identity provider.
  // If a response is received then this is in response to single logout having been initiated by the service provider.
  var sloResult = await _samlServiceProvider.ReceiveSloAsync();

  if (sloResult.IsResponse)
  {
    // Respond to the SP-initiated SLO request indicating successful logout.
    await _samlIdentityProvider.SendSloAsync();  
  }
  else
  {
  }

  return new EmptyResult();
}

PS: не забудьте обновить свойства SingleLogoutServiceUrl , если в итоге вы создадите две разные конечные точки для обработки выхода из системы.

...