Rails 多个组织的单点登录和 SAML

Rails Single Sign On and SAML For Multiple Organizations

这更像是一个建议问题,而不是一个具体的实施问题。

目前,对于我在 Rails 项目上的 Ruby,我正在使用 Devise 来管理用户。我还有一个模型 Account 这样每个用户都属于一个帐户,一个帐户有很多用户。一个帐户可以被认为是一个组织或公司,或者基本上是我的一个客户。

我有很多账户(即很多客户)。现在他们中的一个将我的产品与他们自己或其他供应商开发的许多其他网络应用程序一起使用。该客户(帐户)希望允许单点登录我的产品以及他们自己或其他供应商的其他产品。我已经使用 Devise 和 Devise_Saml_Authenticatable 宝石实施了一个解决方案,Okta 作为身份提供者,它适用于那个客户(帐户)。

但是,通过该实现,必须首先在 Okta 上创建所有帐户的所有用户,当他们登录时,他们都需要通过 Okta 的单点登录过程,这不是我想要的。我希望不需要 SSO 的帐户用户仅使用默认登录页面并登录,而无需对 Okta 执行任何操作。

我的用户模型如下所示:

class User < ApplicationRecord
  rolify
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :rememberable, :trackable, :validatable, :recoverable, :timeoutable, :session_limitable, :saml_authenticatable

我的涉及 devise 和 devise_saml_authenticatable 的路线声明为:

devise_for :users, skip: [:sessions] 生成的路线是:

 new_user_password GET      /users/password/new(.:format)                            devise/passwords#new
                       edit_user_password GET      /users/password/edit(.:format)                           devise/passwords#edit
                            user_password PATCH    /users/password(.:format)                                devise/passwords#update
                                          PUT      /users/password(.:format)                                devise/passwords#update
                                          POST     /users/password(.:format)                                devise/passwords#create
                 cancel_user_registration GET      /users/cancel(.:format)                                  devise/registrations#cancel
                    new_user_registration GET      /users/sign_up(.:format)                                 devise/registrations#new
                   edit_user_registration GET      /users/edit(.:format)                                    devise/registrations#edit
                        user_registration PATCH    /users(.:format)                                         devise/registrations#update
                                          PUT      /users(.:format)                                         devise/registrations#update
                                          DELETE   /users(.:format)                                         devise/registrations#destroy
                                          POST     /users(.:format)                                         devise/registrations#create
                         new_user_session GET      /users/saml/sign_in(.:format)                            devise/saml_sessions#new
                             user_session POST     /users/saml/auth(.:format)                               devise/saml_sessions#create
                     destroy_user_session DELETE   /users/sign_out(.:format)                                devise/saml_sessions#destroy
                    metadata_user_session GET      /users/saml/metadata(.:format)                           devise/saml_sessions#metadata
                idp_sign_out_user_session GET|POST /users/saml/idp_sign_out(.:format)                       devise/saml_sessions#idp_sign_out
                                 new_user GET      /users/new(.:format)                                     users#new
                                edit_user GET      /users/:id/edit(.:format)                                users#edit
                                     user PATCH    /users/:id(.:format)                                     users#update
                                          PUT      /users/:id(.:format)                                     users#update

请注意,我必须执行 skip: [:sessions],否则会出现错误 ArgumentError: Invalid route name, already in use: 'new_user_session' You may have defined two routes with the same name using the:asoption, or you may be overriding a route already defined by a resource with the same naming.

我最大的问题是:

假设我有一个客户(客户 A)想要在我的应用程序和仅由该客户 A 管理的其他应用程序上使用 SSO,并且有另一个客户(客户 B)想要在我的应用程序和由该客户 A 管理的其他应用程序上使用 SSO仅客户 B,另一个客户 C 不想要 SSO,只想要旧的 Devise 登录方法;并且客户之间不共享任何用户信息(我认为这需要客户 A、B 提供他们自己的身份提供者)。有办法吗?请注意,对于客户 C,由于上述冲突错误,我当前的设计会话路由无法工作。

谢谢!

您将需要两个单独的登录流程。通常网站会有一个普通的登录表单,也有一个 "Login with [insert idp here]" 按钮。单击按钮,前往 idp,登录,返回到特定的 saml 端点,该端点在本地登录并离开。

您的所有用户都会看到 saml 登录按钮,除非您为您的 saml 客户提供不同的登录页面供他们使用,但拥有这些按钮确实没有问题,它们现在无处不在!即使是堆栈,您也可以使用 google.

登录