2

Я пытаюсь настроить приложение Ruby on Rails, ActiveAdmin, которое использует для проверки подлинности Devise. Я использую Azure AD strategy для стратегии omniauth.Как установить приложение RoR с SSO на Azure AD

Я добавил OmniAuth стратегии в config/initializers/devise.rb:

config.omniauth :azure_activedirectory, 'app id', 'azure tenant id' 

Добавлен Users::OmniauthCallbacksContoller:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController 
    def azure_activedirectory 
    @user = AdminUser.from_omniauth(request.env['omniauth.auth']) 

    if @user.persisted? 
     sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated 
     set_flash_message(:notice, :success, :kind => 'azure_activedirectory') if is_navigational_format? 
    else 
     session['devise.azure_activedirectory_data'] = request.env['omniauth.auth'] 
     redirect_to new_admin_user_registration_url 
    end 
    end 

    def failure 
    redirect_to root_path 
    end 
end 

И добавил обратный вызов маршруты в routes.rb:

Rails.application.routes.draw do 
    devise_config = ActiveAdmin::Devise.config 
    devise_config[:controllers][:omniauth_callbacks] = 'users/omniauth_callbacks' 
    devise_for :admin_users, devise_config 

    devise_scope :admin_user do 
    get 'sign_in', :to => 'devise/sign_in', as: :new_admin_user_session 
    get 'sign_out', :to => 'devise/sign_out', :as => :destroy_admin_user_session 
    end 

    ActiveAdmin.routes(self) 

    root to: redirect('/admin') 
end 

Добавлен from_omniauth методаmodels/admin_user:

class AdminUser < ActiveRecord::Base 
    devise :trackable, :omniauthable, omniauth_providers: [:azure_activedirectory] 

    def self.from_omniauth(auth) 
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user| 
     user.email = auth.info.email 
     user.password = Devise.friendly_token[0,20] 
    end 
    end 
end 

Но все, что я получаю, когда я запустить приложение является ошибка: The action 'sign_in' could not be found for Users::OmniauthCallbacksController

Я к концу сейчас, я не знаю, что еще я должен сделать, чтобы заставить его работать. https://github.com/AzureAD/omniauth-azure-activedirectory и https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview больше не показывать ни одной записи о том, как ее исправить.

Может ли кто-нибудь помочь мне в том, что я делаю неправильно?

ответ

4

Мы работаем над проектом немного больше и смогли решить аутентификацию Azure AD.Однако есть несколько вещей, с которыми мы сталкиваемся.

По умолчанию стратегия активного каталога azure генерирует маршруты без подчеркивания. Таким образом, убедитесь, что модель, используемая для аутентификации используется:

omniauth_providers: [:azureactivedirectory]

Модели также был расширен с полей «поставщиком» и «UID».

Devise добавит ссылку (c.q. button) на страницу для входа. Но наша цель - поддерживать только аутентификацию omniauth, не имея дополнительной страницы входа в систему. Чтобы достичь этого, мы добавили перенаправление, чтобы получить возможность перенаправлять аутентификацию прямо на лазурный провайдер.

Также будьте осторожны при изменении отображения (в config/initializers/device.rb). Мы добавили обходной путь в случае, если Devise не смог найти обработчик ошибок аутентификации для области: api. В нашем случае мы оказались в цикле, так как из-за сопоставления аутентификация не была правильно установлена ​​в нашем приложении. Наше приложение направил нас к Azure для проверки подлинности, в то время как Azure перенаправлены нас, потому что мы были проверены уже, с последующим применением направляя нас ... и т.д.

Ниже приведены несколько фрагментов кода, которые могут быть полезны:

конфигурации/routes.rb

Rails.application.routes.draw do 

    devise_config = ActiveAdmin::Devise.config 
    # see https://github.com/activeadmin/activeadmin/wiki/Log-in-through-OAuth-providers 
    # for how to combine settings in devise config from ActiveAdmin and SamlSessions 
    devise_config[:controllers][:omniauth_callbacks] = 'omniauth_callbacks' 
    devise_config[:skip] = [:sessions] 
    devise_for :admin_users, devise_config 

    devise_scope :admin_user do 
    get 'sign_in', :to => redirect('/admin/auth/azureactivedirectory'), :as => :new_admin_user_session 
    get 'sign_out', :to => 'devise/sessions#destroy', :as => :destroy_admin_user_session 
end 

ActiveAdmin.routes(self) 
... 
... 

приложение/модели/admin_user.rb

class AdminUser < ActiveRecord::Base 

    devise :trackable, :omniauthable, omniauth_providers: [:azureactivedirectory] 

    def self.from_omniauth(auth) 
    where(provider: auth['provider'], uid: auth['uid']).first_or_create do |user| 
     user.email = auth['info']['email'] 
    end 
    end 
end 

приложение/контроллеры/omniauth_callbacks_controller.rb

class OmniauthCallbacksController < Devise::OmniauthCallbacksController 
    skip_before_filter :verify_authenticity_token 

    def azureactivedirectory 
    @user = AdminUser.from_omniauth(request.env['omniauth.auth']) 

    if @user.persisted? 
     sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated 
     set_flash_message(:notice, :success, :kind => 'azure_activedirectory') if is_navigational_format? 
    else 
     session['devise.azure_activedirectory_data'] = request.env['omniauth.auth'] 
     redirect_to new_admin_user_registration_url 
    end 
    end 

    def failure 
    redirect_to root_path 
    end 
end 
0

Я не думаю, что вам нужна эта строка:

get 'sign_in', :to => 'devise/sign_in', as: :new_admin_user_session 

На Devise Docs он говорит, что если вы используете:

devise_for :admin_users 

Разрабатывают будет автоматически создавать маршруты для входа в систему, так что вы просто необходимо использовать:

<%= link_to "Sign in with AzureAD", admin_user_omniauth_authorize_path(:azure_activedirectory) %> 

Надеюсь, это вам поможет :)

UPDATE

При входе в систему, вы можете указать путь, который вы хотите, чтобы пользователь будет перенаправлен, как вы можете видеть here и here, чтобы сделать это, Вы можете указать такие методы, как это на ваше приложение контроллер:

def after_sign_in_path_for(resource) 
    current_user_path 
end 

и

def after_sign_out_path_for(resource_or_scope) 
    request.referrer 
end 

ОБНОВЛЕНИЕ 2

Вы перенаправляют от «/» до «/ администратора», потому что эта линия на вашей конфигурации/routes.rb

root to: redirect('/admin') 

Это установка корень вашего приложения, которое по умолчанию это/'to'/admin '. Если вы удалите эту строку, рельсы распознают корень вашего приложения как «/».

+0

Спасибо за попытку помочь. Слишком плохо, хотя это решает ошибку, но вводит новую проблему: я перенаправляюсь из '/' в '/ admin' и наоборот. –

+0

@MichaelSommer Я отредактировал свой ответ, чтобы попытаться решить вашу проблему, надеюсь, что он работает для вас сейчас. –

+0

Когда я удаляю «root to:», люди больше не будут перенаправлены на '/ admin', и я не ожидаю, что мои пользователи сами это узнают. У моего корня есть запись для api, которая использует Warden вместо разработки. –

Смежные вопросы