devise_saml_authenticatable
devise_saml_authenticatable copied to clipboard
Multiple Authentication strategies with user STI
I have been trying to implement multiple authentication strategies with single table inheritance. Right now it is SAML and database authenticatable, but the STI allows for us to add LDAP in the future. Our use of STI seems to make it different from the method suggested here, https://github.com/apokalipto/devise_saml_authenticatable/wiki/Supporting-multiple-authentication-strategies.
I have the Database Authenticatable user working fine and the SAML user starts the process fine. I send the SAML request and then I process the SAML response and create the session. There is a current_user and session. However, on the last redirect back to our root path, the current_user falls out of the session. I think it might be at the last line of the session create method inherited from Devise. I am a little confused as to why this might be. I am not sure whether opening an issue makes the most sense, but I was hoping for some potential insite into why this might be happening.
Our code base can be found here, this is a feature branch so it still has some issues with specs: https://github.com/NUARIG/competitions/tree/feature/add-registered-users-554
Again, please close this issue if you (@adamstegman ) think it is inappropriate. I am working through the multiple authentication method described in the wiki. I am now working through how to deal with the devise functionality for the following. I am interested to see how this experiment works out. Right now we are having trouble with confirmable.
:trackable,
:timeoutable
:confirmable,
:registerable,
:rememberable,
:recoverable,
:validatable
We also use STI, but our user types don't share access, i.e. one type of user has access to some routes, and the other type of user has access to different routes. So we use authenticate_<subclass>! and current_<subclass> instead of authenticate_user! and current_user. We also don't use most of those plugins, so I don't have any direct experience with them.
I'm interested to see what you find! I wouldn't expect to find any conflicts between the plugins, but configuring all of this is always a challenge.
@adamstegman, it isn't making a lot of sense to me. There is a @current_saml_user in the session and then there isn't. Here is a clip of the log from where it falls out. There are a bunch of extra print statements in here also.
SamlUser Load (9.1ms) SELECT "users".* FROM "users" WHERE "users"."type" IN ('SamlUser') AND "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["email", "[email protected]"], ["LIMIT", 1]]
↳ /Users/mjb0760/.rvm/gems/ruby-2.6.6/bundler/gems/devise_saml_authenticatable-fc398ff221cd/lib/devise_saml_authenticatable.rb:123
(0.4ms) BEGIN
↳ /Users/mjb0760/.rvm/gems/ruby-2.6.6/bundler/gems/devise_saml_authenticatable-fc398ff221cd/lib/devise_saml_authenticatable.rb:110
User Exists (0.8ms) SELECT 1 AS one FROM "users" WHERE "users"."uid" = $1 AND "users"."id" != $2 LIMIT $3 [["uid", "[email protected]"], ["id", 1], ["LIMIT", 1]]
↳ /Users/mjb0760/.rvm/gems/ruby-2.6.6/bundler/gems/devise_saml_authenticatable-fc398ff221cd/lib/devise_saml_authenticatable.rb:110
User Exists (3.8ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 AND "users"."id" != $2 LIMIT $3 [["email", "[email protected]"], ["id", 1], ["LIMIT", 1]]
↳ /Users/mjb0760/.rvm/gems/ruby-2.6.6/bundler/gems/devise_saml_authenticatable-fc398ff221cd/lib/devise_saml_authenticatable.rb:110
(0.4ms) COMMIT
↳ /Users/mjb0760/.rvm/gems/ruby-2.6.6/bundler/gems/devise_saml_authenticatable-fc398ff221cd/lib/devise_saml_authenticatable.rb:110
(0.3ms) BEGIN
↳ /Users/mjb0760/.rvm/gems/ruby-2.6.6/bundler/gems/devise_saml_authenticatable-fc398ff221cd/lib/devise_saml_authenticatable/model.rb:17
(0.3ms) COMMIT
↳ /Users/mjb0760/.rvm/gems/ruby-2.6.6/bundler/gems/devise_saml_authenticatable-fc398ff221cd/lib/devise_saml_authenticatable/model.rb:17
(3.1ms) BEGIN
↳ app/controllers/application_controller.rb:52
SamlUser Update (1.6ms) UPDATE "users" SET "updated_at" = $1, "sign_in_count" = $2, "current_sign_in_at" = $3, "last_sign_in_at" = $4 WHERE "users"."id" = $5 [["updated_at", "2020-08-05 17:11:18.024227"], ["sign_in_count", 775], ["current_sign_in_at", "2020-08-05 17:11:18.019272"], ["last_sign_in_at", "2020-08-05 17:09:55.832274"], ["id", 1]]
↳ app/controllers/application_controller.rb:52
PaperTrail::UserVersion Create (6.2ms) INSERT INTO "user_versions" ("item_type", "item_id", "user_id", "event", "object", "created_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["item_type", "User"], ["item_id", 1], ["user_id", 1], ["event", "update"], ["object", "---\nid: 1\nemail: [email protected]\nfirst_name: John\nlast_name: Doe\nuid: [email protected]\nera_commons: ''\nsystem_admin: true\ncreated_at: 2019-09-12 15:58:12.641988000 -05:00\nupdated_at: 2020-08-05 17:09:55.833810000 -05:00\nremember_created_at: \nsign_in_count: 774\ncurrent_sign_in_at: 2020-08-05 17:09:55.832274000 -05:00\nlast_sign_in_at: 2020-08-05 17:08:55.692212000 -05:00\ncurrent_sign_in_ip: 127.0.0.1/32\nlast_sign_in_ip: 127.0.0.1/32\ngrant_creator: true\ntype: SamlUser\nencrypted_password: ''\nreset_password_token: \nreset_password_sent_at: \nconfirmation_token: \nconfirmed_at: \nconfirmation_sent_at: \nunconfirmed_email: \n"], ["created_at", "2020-08-05 17:11:18.024227"]]
↳ app/controllers/application_controller.rb:52
(1.6ms) COMMIT
↳ app/controllers/application_controller.rb:52
~~~~~USER_SIGNED_IN: true
~~~~CURRENT_USER: true
~~~~CURRENT_USER: true
~~~~CURRENT_USER: true
(0.5ms) BEGIN
↳ app/controllers/application_controller.rb:31
AuditAction Create (4.0ms) INSERT INTO "audit_actions" ("user_id", "controller", "action", "browser", "params", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["user_id", "1"], ["controller", "saml_sessions"], ["action", "/saml_users/saml/auth"], ["browser", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:78.0) Gecko/20100101 Firefox/78.0"], ["params", "{\"RelayState\"=>\"http://localhost:3000/\", \"SAMLResponse\"=>\"..."}"], ["created_at", "2020-08-05 17:11:18.196938"], ["updated_at", "2020-08-05 17:11:18.196938"]]
↳ app/controllers/application_controller.rb:31
(0.9ms) COMMIT
↳ app/controllers/application_controller.rb:31
SSC CREATE @@@@@@@@@@@@@@@@@@@@@@
[i18n-debug] en.devise.sessions.saml_user.signed_in => nil
[i18n-debug] en.devise.sessions.signed_in => "Signed in successfully."
^^^^^^^^^^^SIGNIN^^^^^^^^
^^^^^^^^^^^IN THE ELSIF^^^^^^^^
RESOURCE: #<SamlUser id: 1, email: "[email protected]", first_name: "John", last_name: "Doe", uid: "[email protected]", era_commons: "", system_admin: true, created_at: "2019-09-12 20:58:12", updated_at: "2020-08-05 22:11:18", grant_creator: true>
Redirected to http://localhost:3000/
~~~~~USER_SIGNED_IN: true
~~~~CURRENT_USER: true
~~~~CURRENT_USER: true
SESSION_INDEX_KEY: _591b1d61-7a56-4964-b4b1-8826cd32e55e
Completed 302 Found in 742ms (ActiveRecord: 113.3ms)
Started GET "/" for 127.0.0.1 at 2020-08-05 17:11:18 -0500
Processing by HomeController#index as HTML
SamlUser Load (6.1ms) SELECT "users".* FROM "users" WHERE "users"."type" IN ('SamlUser') AND "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:44
SAML_USER_SIGNED_IN: false
Redirected to http://localhost:3000/login
Filter chain halted as :authenticate_user! rendered or redirected
Completed 302 Found in 16ms (ActiveRecord: 6.1ms)
Started GET "/login" for 127.0.0.1 at 2020-08-05 17:11:18 -0500
Processing by LoginController#index as HTML
~~~~~USER_SIGNED_IN: false
~~~~CURRENT_USER: false
Rendering login/index.html.haml within layouts/application
Rendered login/_login.html.haml (11.2ms)
Rendered login/index.html.haml within layouts/application (21.4ms)
~~~~~USER_SIGNED_IN: false
Rendered layouts/_header_help_links.html.haml (5.9ms)
~~~~~USER_SIGNED_IN: false
Rendered devise/menu/_login_items.html.haml (7.8ms)
Rendered layouts/_header.html.haml (28.3ms)
Rendered shared/_flash_messages.html.haml (6.7ms)
Rendered layouts/_flash.html.haml (12.0ms)
Rendered layouts/_footer.html.haml (17.9ms)
Completed 200 OK in 1003ms (Views: 998.2ms | ActiveRecord: 0.0ms)
and some of the extra methods in the application controller.
# Devise methods
def authenticate_user!
# store_location_for(:registered_user, request.original_url)
# store_location_for(:saml_user, request.original_url)
unless (saml_user_signed_in? || registered_user_signed_in?)
flash[:alert] = 'You need to sign in or sign up before continuing.'
redirect_to login_index_url
end
end
def user_signed_in?
saml_user_signed_in? || registered_user_signed_in?
end
def current_user
current_saml_user || current_registered_user
end
def after_sign_in_path_for(resource)
stored_location_for(resource) || root_path
end
@adamstegman , so far, I think the only conflict is with confirmable. I think you need to somehow set a value for user.confirmed_at on user creation from the saml response. If not, it will continue to force the user to the error screen that you need to confirm your email. That is what I am exploring now. We'll see how it comes together.
Sorry I should add that I am running two separate instances trying to get this running. One we ran into the problems above with the loss of the current_saml_user for the STI instance.
I am also trying to work through a second instance using the method in the wiki here with the winning_strategy. That has some problems with certain validations on the SAML users. Confirmable and now I am running into password requirements on new user creation coming in from the SAML IDP.