Сбой рабочего процесса SAML платформы Google Cloud Identity (CICP)

Задний план

Использование Firebase Auth и SAML Auth Provider со следующей конфигурацией:

const config = {
    apiKey: "AIzaSy...",
    authDomain: "example-app.firebaseapp.com",
};

firebase.initializeApp(config);

const provider = new firebase.auth.SAMLAuthProvider('saml.example-idp');

function saml() {
    firebase.auth().signInWithRedirect(provider)
        .then((result) => {
            console.log(result);
        })
        .catch((error) => {
            console.log(error);
        });
}

В конфигурации CICP для восходящего потока SAML есть поставщик услуг: наш идентификатор объекта и ACS, настроенный как наш CICP. https://example-app.firebaseapp.com/__/auth/handler.

Что я ожидаю произойти

Чтобы иметь возможность установить точку останова в signInWithRedirect()обещание then и увидеть аутентифицированного пользователя.

Что на самом деле происходит

Поток перенаправляется к IdP, и выполняется аутентификация.

IdP выдает страницу перенаправления с автоматической отправкой при загрузке и multipart/form-data форма с:

  • Content-Disposition: форма-данные; name=SAMLResponse - содержащий подписанный SAMLResponse в кодировке base64
  • Content-Disposition: форма-данные; name=RelayState - содержит состояние реле из потока SAML
  • Content-Disposition: форма-данные; name="ssourl" - содержащий URI обработчика аутентификации проекта firebase

Это, в свою очередь, заставляет CICP отображать и возвращать страницу со скриптом, который устанавливает

var POST_BODY=""------WebKitFormBoundary9bn7AOpnZiIRk9qZ\r\nContent....."

т.е. вместо того, чтобы анализировать тело формы и извлекать поле SAMLResponse, он воспроизводит весь Request.body в скрипте, а затем вызывает fireauth.oauthhelper.widget.initialize();

Это, очевидно, не удается, потому что эти обходы, а затем попытки отправить все тело ответа в /__/auth/handler конечная точка как строка запроса.

Я подозреваю, что в этой цепочке отсутствует простой элемент конфигурации, потому что все потоки выглядят нормально для меня, пока данные из составной формы не будут помещены в POST_BODY, а затем не предотвратят преобразование токена SAML в токен OAuth.

Вопрос

Какой элемент конфигурации неверен в этой (отредактированной) настройке и каков правильный вывод значения для его замены?

2 ответа

Решение

Краткий ответ на длинный вопрос:

Обработка поставщика SAML в Firebase Auth и Google CICP не обрабатывается multipart/form-data и должен быть в application/x-www-form-urlencoded.

Это конфигурация SAML IdP, а не то, что может быть обработано конфигурацией поставщика службы Firebase Auth.

Возможно, с SAML есть еще одна техническая проблема, но, по крайней мере, в этом есть некоторая несогласованность. sign-in используется метод.

Согласно (Официальные документы)[https://cloud.google.com/identity-platform/docs/how-to-enable-application-for-saml, у вас есть 2 варианта для входа:

1) Со всплывающим окном

В этом случае вы можете использовать обещание для получения user credential с sign-in метод:

firebase.auth().signInWithPopup(provider)
    .then((result) => {
      // User is signed in.
      // Identity provider data available in result.additionalUserInfo.profile,
      // or from the user's ID token obtained via result.user.getIdToken()
      // as an object in the firebase.sign_in_attributes custom claim
      // This is also available via result.user.getIdTokenResult()
      // idTokenResult.claims.firebase.sign_in_attributes.
    })
    .catch((error) => {
      // Handle error.
    });

2) С перенаправлением

В этом случае ваш код следует разбить на 2 части. Первыйsign-in метод без использования обещаний:

 firebase.auth().signInWithRedirect(provider);

Затем инициализация "слушателя" для получения учетных данных пользователя после перенаправления входа:

// On return.
firebase.auth().getRedirectResult()
    .then((result) => {
      // User is signed in.
      // Identity provider data available in result.additionalUserInfo.profile,
      // or from the user's ID token obtained via result.user.getIdToken()
      // as an object in the firebase.sign_in_attributes custom claim
      // This is also available via result.user.getIdTokenResult()
      // idTokenResult.claims.firebase.sign_in_attributes.
    })
    .catch((error) => {
      // Handle error.
    });  

Будет добавлено в загрузочную часть вашей страницы / приложения.

Надеюсь, это поможет.

Другие вопросы по тегам