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

时间:2019-02-21 15:05:29

标签: ruby-on-rails devise single-sign-on saml

这更多是关于建议问题,而不是特定的实施问题。

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

我有很多帐户(即很多客户)。现在,其中一个将我的产品与自己或其他供应商开发的许多其他Web应用程序一起使用。该客户(帐户)希望允许单次登录我的产品以及自己或其他供应商的其他产品。我已经实现了一个使用Devise和Devise_Saml_Authenticatable gem的解决方案,并以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:as option, or you may be overriding a route already defined by a resource with the same naming.

我最大的问题是:

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

谢谢!

1 个答案:

答案 0 :(得分:1)

您将需要两个单独的登录流程。通常,站点将具有正常的登录表单,该表单也具有“使用[在此处插入idp登录]”登录按钮。单击该按钮,进入idp,登录,然后发送回特定的saml端点,该端点在本地登录并离开。

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

相关问题