0

OmniAuth 2.0 要求对 IdP 身份验证服务器的请求是 POST 而不是 GET。

对于大多数用户来说,这意味着在他们的登录页面上,他们有指向 Facebook 和 Google 等 OmniAuth 提供商的链接,他们将这些链接或按钮上的方法更改为 POST。没问题。

但是对于我的一个应用程序,我们想要它,以便如果身份验证失败(例如进入应用程序并且您仍然需要登录),我们将自定义 Devise::Failure 应用程序重定向到 IdP 身份验证服务器。当然,这意味着您通过 GET 请求来到我们的应用程序,我们发现您未通过身份验证,因此我们将您重定向到 IdP。但我们不能再这样做了,因为它必须是一个 POST。我能看到的唯一方法是我必须删除我们的自定义失败应用程序,以便您被重定向到我们指向 IdP 的链接所在的正常登录页面。

关于如何保持当前重定向直接到 IdP 逻辑的任何想法?

4

1 回答 1

0

答案是 OmniAuth 2.0 无法做到这一点。您将无法将您的 DeviseFailureApp 重定向到 IdP 的登录页面,因为这将是一个 GET。

相反,让您的失败应用程序将 redirect_url 返回到您可以添加到 SessionsController 中的新控制器操作。我称它为 saml_redirect。为它添加一条路线:

  devise_scope :user do
    match 'saml_redirect' => 'sessions#saml_redirect', as: :saml_redirect, via: [:get]
  end

该控制器操作实际上不需要执行任何操作,只需渲染一个 .html.erb。在那个 html.erb 中,只需有一个隐藏按钮,它将向 IdP 的登录页面执行 POST,就像您有一个 Facebook 按钮并且用户单击它一样。然后当页面加载时,您会自动单击该按钮。这是 html.erb 的完整代码:

<div class="info_box">You are being redirected to your corporate network sign-in page</div>
<%= button_to "Login with #{ENV['saml_idp_name']}", user_saml_omniauth_authorize_path(provider: :saml), method: :post, id: 'saml_button', style: 'display: none' %>
<script>
  function ready(callbackFunction){
    if(document.readyState != 'loading')
      callbackFunction();
    else
      document.addEventListener("DOMContentLoaded", callbackFunction);
  }
  ready(() => {
    document.getElementById('saml_button').click();
  })
</script>

所以这里没有火箭科学。游戏的名称是,如果您希望用户在需要登录时自动转到身份提供者的页面,而不是强迫他们从您的登录页面单击按钮,那么您只需自动单击按钮即可。

于 2021-05-19T18:38:35.860 回答