Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hooks around AuthorizationController / Single Sign Out feature #1062

Closed
nattfodd opened this issue Mar 22, 2018 · 5 comments
Closed

Hooks around AuthorizationController / Single Sign Out feature #1062

nattfodd opened this issue Mar 22, 2018 · 5 comments

Comments

@nattfodd
Copy link
Contributor

nattfodd commented Mar 22, 2018

Hey there! I'm working on the Single Sign Out feature in my project, which actually means:

Once the user signs out from the service application, it should be also signed out from any other connected services, including the primary one (auth provider).

There's an example of how Google does that - http://romain.pechayre.me/blog/2015/06/26/single-sign-out-problem/ - and I've tried to implement it in the same way.

The idea I've ended up with is to store in the main auth cookies a list of service applications, that have requested the auth. And upon logout, on the side of the every service application there should be a redirection to auth-provider.com/logout which redirects user back to every logged in service and forces him to log out.

The code is pretty simple, but it requires monkey-patching Doorkeeper, which isn't very good idea considering I had to copy-paste parts of existing code that might change in the future:

# config/initializers/doorkeeper.rb
Doorkeeper::AuthorizationsController.class_eval do
  def new
    return render :error unless pre_auth.authorizable?

    if skip_authorization? || matching_token?
      auth = authorization.authorize
      store_logout_url!(auth) # this is the monkey patched line
      redirect_to auth.redirect_uri
    else
      render :new
    end
  end

  private

  def store_logout_url!(auth)
    session[:logouts] =
      (session.fetch(:logouts, []) + [logout_path(auth)]).uniq.compact
  end

  def logout_path(auth)
    uri = URI.parse(auth.redirect_uri)
    uri.path = '/logout'
    uri.to_s
  end
end

And then in some SessionsController:

class SessionsController < ApplicationController
  # DELETE /logout
  def destroy
    service_logout_url = session[:logouts].delete_at(0)
    return session[:user_id] = nil unless service_logout_url

    redirect_to service_logout_url
  end
end

This seems to work (besides possible too many redirections error), but since I had to monkey-patch Doorkeeper I have the following questions:

Is there a chance to add some hooks to AuthorizationsController?

So on the client side it might be something like:

Doorkeeper.configure do
  after_authorization do |auth|
    # some custom code needed to be performed after access is granted, i.e.:
    store_logout_url!(auth) 
  end
end

Maybe that feature (Single Sign Out) could be interesting to the users?

In case I could propose a PR to add that opt'able feature to the gem.

@nbulaj
Copy link
Member

nbulaj commented Mar 22, 2018

How about to use before_successful_response and after_successful_response hooks?

before_successful_strategy_response and after_successful_strategy_response options of Doorkeeper configuration (available from 4.3.1).

@nattfodd
Copy link
Contributor Author

nattfodd commented Mar 22, 2018

@nbulaj thank you for the response!

Unfortunately, it seems before_successful_strategy_response and after_successful_strategy_response don't have access to sessions...

@nbulaj
Copy link
Member

nbulaj commented Mar 23, 2018

Maybe you can make some research if we can add a context to existing hooks in order to provide required binding? If it is hard to implement, you can send a PR with before and after hooks for authorization 👍

@nattfodd
Copy link
Contributor Author

@nbulaj can you please take a look at #1064 ?

@nbulaj
Copy link
Member

nbulaj commented Mar 31, 2018

Merged, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants