Wednesday, October 4, 2017

Setting up SAML callback in Rails using Devise and OmniAuth-SAML

Leave a Comment

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?):

rails_error_message

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.

1 Answers

Answers 1

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 Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment