EDIT: Additional info and condensed question near the bottom ;)
I'm setting up integration between a small app I'm making and an identity provider using SAML2.0.
In general, I've been following the instructions on the Devise page, and then on the Omniauth-SAML docs.
The issue seems currently to be that no callback path has been generated. Here's the relevant code bits below; feel free to request additional information.
app/models/user.rb
class User < ActiveRecord::Base
devise :omniauthable, omniauth_providers: [:saml]
def from_omniauth(auth_hash)
puts auth_hash
new # Stub for now I guess?
end
end
app/controllers/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def saml
@user = User.from_omniauth request.env['omniauth.auth']
if @user.persisted?
sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: 'SAML') if is_navicational_format?
else
session['devise.saml_data'] = request.env['omniauth.auth']
redirect_to permission_denied # this isn't going to work lol
end
end
def failure
redirect_to root_path
end
end
A truncated & sanitized chunk from config/initializers/devise.rb
config.omniauth :saml,
idp_cert_fingerprint: 'aa:bb:cc...', # an actual fingerprint here
idp_sso_target_url: 'https://sso.bla.thing.com/fss/idp/startSSO.ping?PartnerSpId=SAML_UID',
issuer: 'myidpname', # Not actually sure what this should be
idp_entity_id: 'thingfssdp',
assertion_consumer_service_url: 'https://myapp.com/auth/saml/callback',
name_identifier_format: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'
According to the docs here and here, adding more than the above (that is, putting the additional requirements into config/initializers/omniauth.rb) would be incorrect.
My controllers have before_action :authenticate_user!
as their first line.
config/routes.rb has the following line at the top:
Rails.application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
But it's possibly important to note that I haven't manually added any logic for callback handling yet
Attempting to visit my app yields an ERR_TOO_MANY_REDIRECTS; quite a few 302s all apparently pointing back to itself. Doing a GET /auth/saml/callback yields the following helpful error (not sure how or why /users/ gets prepended there; do I need to request a change in ACS URL or is this something I have control of?):
Any insight or assistance would be much appreciated.
EDIT: It looks as though the issue is that user_saml_omniauth_authorize_path
is being set to /users/auth/saml -- and not directly the IDP signin page. I have no explicit controller for this route, but apparently requiring signin for OTHER controllers means I am requiring signin for this one. The end result is that, as some have suggested, we get an infinite redirect loop.
About the redirect loop: Since you have before_action :authenticate_user!
it leads any unauthenticated request to users sign in page. My guess is that you also have the same callback on your sign in page. Thus on every redirect to /sign_in
rails puts it through this authenticate_user!
and redirects it again since user is not authenticated. For it to work correctly you have to skip_before_action :authenticate_user!
in the controller where you have the sign on (SessionsController I presume).
As for your second question - the correct authorization route. the answer is in the screenshot you presented, below the error. You can see there that the correct path is /users/auth/saml
and users/auth/saml/callback
UPDATE: users gets prepended by default from Devise (using your devisable model name)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With