【问题标题】:Google Cloud Identity Platform (CICP) SAML Workflow FailsGoogle Cloud Identity Platform (CICP) SAML 工作流失败
【发布时间】:2020-02-05 16:44:32
【问题描述】:

背景

使用 Firebase 身份验证和具有以下配置的 SAML 身份验证提供程序:

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);
        });
}

SAML 上游的 CICP 配置具有服务提供者:我们的实体 id 和配置为我们的 CICP https://example-app.firebaseapp.com/__/auth/handler 的 ACS。

我预计会发生什么

为了能够在signInWithRedirect()的Promise的then中设置断点并查看经过身份验证的用户。

实际发生的情况

流被重定向到 IdP 并处理身份验证。

IdP 发出带有自动提交加载的重定向发布页面和multipart/form-data 表单,其中包含:

  • 内容处置:表单数据; name=SAMLResponse - 包含 base64 编码签名 SAMLResponse
  • 内容处置:表单数据; name=RelayState - 包含来自 SAML 流的中继状态
  • 内容处置:表单数据; name="ssourl" - 包含 firebase 项目身份验证处理程序 URI

这反过来又会导致 CI​​CP 呈现并返回带有设置脚本的页面

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

即它不是解析表单正文并提取 SAMLResponse 字段,而是将整个 Request.body 重播到脚本中,然后调用fireauth.oauthhelper.widget.initialize();

这显然失败了,因为往返然后尝试将整个响应正文作为查询字符串发布到 /__/auth/handler 端点。

我怀疑此链中缺少一个简单的配置项,因为在多部分表单数据被推送到 POST_BODY 并阻止将 SAML 令牌转换为 OAuth 令牌之前,所有流程对我来说都是正常的。

问题

在这个(修订的)设置中哪个配置项不正确,替换它的值的正确派生是什么?

【问题讨论】:

    标签: google-cloud-platform firebase-authentication saml-2.0 google-cloud-identity


    【解决方案1】:

    也许 SAML 还存在一个额外的技术问题,但至少在使用 sign-in 方法的方式上存在不一致点。

    根据(官方文档)[https://cloud.google.com/identity-platform/docs/how-to-enable-application-for-saml#handle-signin-with-client-sdk],您有两种登录方式:

    1) 带有弹出窗口

    在这种情况下,您可以使用 Promise 来检索 user credentialsign-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) 使用重定向

    在这种情况下,您的代码应该分成两部分。 第一个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.
        });  
    

    要添加到您的页面/应用程序的引导部分中。

    希望它会有所帮助。

    【讨论】:

    • 很好,我们在页面启动中确实有一个 getRedirectResult(),我将把它添加到问题中。我整天都在与 IdP 运营商和 Google 通电话,可以在问题中提供更多细节。
    【解决方案2】:

    长问题的简短回答:

    在 Firebase Auth 和 Google CICP 中处理的 SAML 提供程序不处理 multipart/form-data,需要在 application/x-www-form-urlencoded 中。

    这是一个 SAML IdP 配置,不是 Firebase 身份验证服务提供者配置可以处理的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-16
      • 2021-01-11
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多