Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google SAML app_not_configured_for_user / equivalent of prompt=select_account SAML

I'm using Gsuite as an Saml IDP to authentify users of my organisation on internal apps.

Everything is working fine, except for one point: when one of my users if logged in with his/her personal account only, Google will fail with:

403 Error: app_not_configured_for_user

This makes sense as the app is intended to be used by internal users only, but I would like to be able to force Google saml authentication to display the account selector even if the user is already logged in to one account as this is possible for oauth2 with prompt=select_account.

Any way to have the same behavior with SAML ?


[EDIT] I actually managed to achieve what I want by using

https://accounts.google.com/AccountChooser/?continue=$SAML_REQUEST$


[EDIT 2] Here is the code snippet for the adaptation in ruby on rails (using ruby-saml)

config/initializers/saml_override.rb

module OneLogin
  module RubySaml
    class Authrequest < SamlMessage
      GOOGLE_ACCOUNT_CHOOSER_URL = "https://accounts.google.com/AccountChooser?continue="
      alias_method :old_create, :create
      def create(settings, params = {})
        self.old_create(settings, params)
        @login_url = GOOGLE_ACCOUNT_CHOOSER_URL + CGI.escape(@login_url)
      end
    end
  end
end
like image 620
Nico Avatar asked Feb 15 '18 11:02

Nico


2 Answers

Good that you've resolved your problem. I thought I'd add a few archirectural points.

SAML

ForceAuthn is a SAML Attribute that you can send in an authentication request. There are others such as EntityId for apps that need to control which login method should be used.

OPENID CONNECT

This has better options I would say, as a more up to date standard. The JOSE based technologies work well for web and mobile clients, in pretty much any tech stack.

There are a greater number of request parameters such as acr_values to replace EntityId, and prompt has more options than ForceAuthn, as you pointed out. This also provides additional session management options as in this recent answer of mine.

PROVIDERS

Not all providers are standards based, and sone may not support ForceAuthn, prompt, acr_values etc, but you may still want to use them for login purposes. To solve your problem you had to resort to a non SAML Google specific request parameter. The more login providers you use, the worse this gets - and application complexity grows.

OPTIMAL ARCHITECTURE

For future reference, it is worth aiming for this architecture, in case any of this is new to you:

  • Application code only uses OpenID Connect, which is a much larger space than many people are aware of - have a look at this summary of standards.

  • Apps only redirect to an Authorization Server, which in turn manages connections to identity providers and their peculiarities. These connections can use SAML, OIDC or anything else needed.

  • The end result should be simple and portable code in apps, which also have support for the most cutting edge authentication flows.

At least that's sonething I like to aim for - identity remains a challenge, sometimes with too many annoyances :).

like image 142
Gary Archer Avatar answered Oct 23 '22 04:10

Gary Archer


class SamlController < ApplicationController

  def init
    request = OneLogin::RubySaml::Authrequest.new
    redirect = request.create(saml_settings)

    # google doesn't support ForceAuthn so we have to redirect requests to the account chooser first
    google_account_url_chooser = "https://accounts.google.com/AccountChooser?continue="
    if redirect.include?("https://accounts.google.com")
      encoded_redirect = CGI.escape(redirect)
      redirect = "#{google_account_url_chooser}#{encoded_redirect}"
    end

    redirect_to(redirect)
  end

  def saml_settings 
    ...
  end
end
like image 2
Neal Soni Avatar answered Oct 23 '22 05:10

Neal Soni