-
Notifications
You must be signed in to change notification settings - Fork 2
Crossdomain authentication
Folio uses Folio::Devise::CrossdomainController
concern to enable one user account to use at many sites. Authentication is done at MASTER site. All SLAVE sites sign in pages are redirected (if needed) to MASTER.
That behavior requires Rails.application.config.folio_crossdomain_devise = true
initializer setting,including Folio::Devise::CrossdomainController
in authentication controllers and overriding Folio.site_for_crossdomain_devise
(to return master site)
Than master site is used to manage users.
Flows goes like this:
-
TARGET SITE 1
-
Going to target site homepage will trigger
CrossdomainHandler.new.handle_before_action!
with:noop
result. So page is displayed. -
Going to sign in page of target site (TSI) will kick in crossdomain controller concern, so it will call
CrossdomainHandler.new.handle_before_action!
-
CrossdomainHandler
will check presence ofparams[:crossdomain]
(not present now) and calls itsauthenticate_user_on_slave_site!
. -
That will
- (re)set key
folio_devise_crossdomain
into target site session"folio_devise_crossdomain":{ "token":"MH8x1xh8fqK_sQPnN7Ku", # <= newly generated "timestamp":"2023-11-23T10:43:30.910+01:00", "resource_name":"user"}}.
- return result
:redirect_to_master_sessions_new
, along with params to pass{ only_path: false, host: master_site.env_aware_domain, crossdomain: "MH8x1xh8fqK_sQPnN7Ku", site: target_site.slug, resource_name: :user, }
- (re)set key
-
Controller will redirect to master site user sign in page (MSI) with such params
-
-
MASTER CROSSDOMAIN SITE
- MSI will also calls
CrossdomainHandler.new.handle_before_action!
-
CrossdomainHandler
will try to readtoken = params[:crossdomain]
(no session on master site yet) andtarget_site_slug = params[:site]
- if they are not present, it will return
:noop
and controller will proceed with controllerssign_in
action - if they are present (and they are now), it will setup key
folio_devise_crossdomain
into master site session withand return"folio_devise_crossdomain":{ "target_site_slug":"target_site_slug", "token":"MH8x1xh8fqK_sQPnN7Ku", "resource_name":"user", "redirected_to_sessions_new":true} }
:noop
to controller. Controller proceed withsign_in
action.
- if they are not present, it will return
- User will fill credential and POST them to MSI.
- MSI will sign in user, creating
current_user
instance. - Than
CrossdomainHandler.new.handle_before_action!
is called, which will RESETcurren_user.crossdomain_devise_token = "newly_generated_value"
andcurrent_user.crossdomain_devise_set_at = Time.current
. And returnsign_in_on_target_site
(which leads to redirecting back to TSI). - Controller redirect to TSI with params
crossdomain=MH8x1xh8fqK_sQPnN7Ku&crossdomain_user=newly_created_value
- MSI will also calls
-
BACK TO TARGET SITE 1
- TSI will trigger again
CrossdomainHandler.new.handle_before_action!
with paramscrossdomain
(already in target site session) andcrossdomain_user
(new to target site). - Crossdomain handler will check these params validity and finds user according to
user.crossdomain_devise_token == params[:crossdomain_user]
. If it exists, keyfolio_devise_crossdomain
is deleted from target site session and:sign_in
(with found user along) is returned to controller. - Controller will do devise own
sign_in(result.resource_name, result.resource)
, settingcurrent_user
(as session key"warden.user.user.key":[[17257],"$2a$11$yStwNX1YFKa4QcbkjM0PGedb628873480393b98cf901d6d1d4a95d"]
) and redirect toafter_sign_in_path_for(result.resource)
. - User is signed in (by devise) at target site, and whenever
CrossdomainHandler.new.handle_before_action!
is called on target site,:noop
is returned
- TSI will trigger again
-
ANOTHER SLAVE SITE (TARGET 2)
- When user comes to another slave site (target2), it is signed out.
CrossdomainHandler.new.handle_before_action!
will return:noop
result. - Going to target2 sign in page (TSI2) triggers
CrossdomainHandler.new.handle_before_action!
and that will resetfolio_devise_crossdomain
key in target2 session and returns:redirect_to_master_sessions_new
(note difference: at 4.1 we are not in devise controller, at 4.2 we are at devise controller). - TSI2 will redirect to master site user sign in page (MSI) with new set of params
crossdomain=CoH_qv7rka1dA4TaKz-C&resource_name=user&site=target2-site
- When user comes to another slave site (target2), it is signed out.
-
MASTER SITE AGAIN
- Master site will load
current_user
and runCrossdomainHandler.new.handle_before_action!
. - That will RESET
user.crossdomain_devise_token = "newly_generated_value2"
anduser.crossdomain_devise_set_at = Time.current
and returns:sign_in_on_target_site
. - Master site controller will redirect back to TSI2 with params
crossdomain=CoH_qv7rka1dA4TaKz-C&crossdomain_user=newly_generated_value2
- Master site will load
-
BACK TO TARGET 2 SITE
- Return to TSI2 continues in same manner as 3.1-3.4. So user is signed in at Target site 2 automagicaly.
-
SIGN OUT ON ANY SLAVE SITE
- Sign out on any of Target sites will lead to sign out on all sites.