devise_saml_authenticatable icon indicating copy to clipboard operation
devise_saml_authenticatable copied to clipboard

Handle missing users when saml_create_user = false

Open andrewfraley opened this issue 7 years ago • 3 comments
trafficstars

I think this might be similar to #122, but I'm not sure. My idp will authenticate all users in my company, however, I only want to grant access to my app for a select list of users. These users are in my users table, and everything works fine for a user present in the table. However, if a user is not present, devise redirects them back to the idp, which then redirects them back to the app, in a loop. What I'd like to do is if a user is not in the users table, then I want to just redirect them to a controller where I can display an error. Any suggestions?

andrewfraley avatar Nov 05 '18 22:11 andrewfraley

I saw your comment on #122 and answered it there, so I'll copy it here:

What I'd like to happen is just redirect the user to a custom controller that can show them an error if they aren't present in my users table.

That I know how to solve! We use a custom Devise::FailureApp to handle failed responses in a situation like that:

class SignInFailure < Devise::FailureApp
  def redirect_url
    if params[:SAMLResponse].present?
      response = OneLogin::RubySaml::Response.new(params[:SAMLResponse])
      invalid_user_session_url(invalid_user_email: response.name_id)
    else
      super
    end
  end

  def respond
    if http_auth?
      http_auth
    else
      redirect
    end
  end
end

Then we have a route set up for the invalid session:

get '/users/invalid', to: 'users#invalid_saml_login', as: :invalid_user_session

And the controller:

before_action :authenticate_user!, except: [:invalid_saml_login]

and the template:

<div>
  <%= params[:invalid_user_email] %> is not authorized. Please <%= link_to 'contact us', 'mailto:' %> or try to <%= link_to "login", new_user_session_path %> again.
</div>

and the devise configuration:

  config.warden do |manager|
    manager.failure_app = SignInFailure
  end

adamstegman avatar Nov 06 '18 18:11 adamstegman

@adamstegman thank you! I was searching for the wrong things. I did end up finding some clear documentation using your method. https://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-a-specific-page-when-the-user-can-not-be-authenticated

sfdc-afraley avatar Nov 06 '18 22:11 sfdc-afraley

Another workarround that worked for me on my implementation is to override auth_options in controller and set recall option.

  def auth_options
    { scope: resource_name, recall: 'users/sessions#new' }
  end

pgouv avatar Jan 27 '21 11:01 pgouv