Google Cloud Identity Platform (CICP) SAML Workflow Fails
使用 Firebase 身份验证和具有以下配置的 SAML 身份验证提供程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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
的 ACS
我期望发生的事情
能够在
实际发生了什么
流被重定向到 IdP 并处理身份验证。
IdP 发出带有自动提交加载的重定向发布页面和一个
-
内容处置:表单数据; name=SAMLResponse - 包含 base64
编码签名 SAMLResponse -
内容处置:表单数据;
name=RelayState - 包含来自 SAML 流的中继状态 -
内容处置:表单数据; name="ssourl" - 包含
firebase 项目身份验证处理程序 URI
这反过来又会导致 CI??CP 呈现并返回一个带有设置脚本的页面
1 2 3 | var POST_BODY=""------WebKitFormBoundary9bn7AOpnZiIRk9qZ\ \ Content....." |
即它不是解析表单正文并提取 SAMLResponse 字段,而是将整个 Request.body 重播到脚本中,然后调用
这显然失败了,因为往返然后尝试将整个响应正文作为查询字符串发布到
我怀疑这个链中缺少一个简单的配置项,因为在多部分表单数据被推送到 POST_BODY 并阻止将 SAML 令牌转换为 OAuth 令牌之前,所有流程对我来说都是正常的。
问题
在这个(编辑的)设置中哪个配置项不正确,替换它的值的正确派生是什么?
长问题的简短回答:
在 Firebase Auth 和 Google CICP 中处理的 SAML 提供程序不处理
这是一个 SAML IdP 配置,不能由 Firebase 身份验证服务提供者配置处理。
也许 SAML 还存在一个额外的技术问题,但至少在
根据(官方文档)[https://cloud.google.com/identity-platform/docs/how-to-enable-application-for-saml#handle-signin-with-client-sdk],您有 2 个登录选项:
1) 带有弹出窗口
在这种情况下,您可以使用 promise 来检索
1 2 3 4 5 6 7 8 9 10 11 12 | 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) 使用重定向
在这种情况下,您的代码应该分成两部分。
第一个
1 | firebase.auth().signInWithRedirect(provider); |
然后,初始化"监听器",在登录重定向后检索用户凭据:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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. }); |
要添加到您的页面/应用程序的引导部分。
希望它会有所帮助。