2

我正在努力設置Ruby on Rails,ActiveAdmin應用程序使用Devise進行身份驗證。我正在使用Azure AD strategy進行omniauth策略。如何在Azure上使用SSO設置RoR應用程序

我已經加入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-activedirectoryhttps://github.com/plataformatec/devise/wiki/OmniAuth:-Overview對於我如何修復它不再顯示任何線索。

任何人都可以幫我解決我做錯的事嗎?

回答

4

我們一直在研究這個項目,並且能夠解決Azure AD身份驗證問題。然而,我們遇到了一些問題。

默認情況下,azure Active Directory策略會生成沒有下劃線的路由。因此請確保用於身份驗證的模型使用:

omniauth_providers: [:azureactivedirectory]

該模型還擴展了字段「provider」和「uid」。

設計將在頁面上添加一個鏈接(c.q.按鈕)來登錄。但我們的目標是僅支持omniauth身份驗證,因此不需要額外的登錄頁面。爲了達到這個目的,我們添加了一個重定向來獲得設計,將身份驗證直接轉發給Azure提供商。

更改映射時(在config/initializers/device.rb中)也要小心。我們添加了一種解決方法,以防Devise無法找到api作用域的認證失敗處理程序。在我們的例子中,我們結束了一個循環,由於映射的原因,我們的應用程序沒有正確設置認證。我們的應用程序指示我們到Azure進行身份驗證,而Azure的重定向我們回,因爲我們已經驗證,其次是應用指導我們...等

下面是一對夫婦的代碼片段,可能是有用的:

的config/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

您在登入時,您可以指定希望用戶被重定向到的路徑,你可以看到herehere,要做到這一點,你可以指定你的應用程序像這些方法控制器:

def after_sign_in_path_for(resource) 
    current_user_path 
end 

def after_sign_out_path_for(resource_or_scope) 
    request.referrer 
end 

UPDATE 2

將您從「/」重定向到「/管理」,因爲這行你的config/routes.rb文件

root to: redirect('/admin') 

這是設置你的應用程序的根,其默認情況下它「 /'到'/ admin'。如果您刪除此行,則rails會將應用程序的根識別爲「/」。

+0

感謝您嘗試幫助。太糟糕了,雖然這解決了錯誤,但引入了一個新問題:我從'/'重定向到'/ admin',反之亦然。 –

+0

@MichaelSommer我編輯了我的答案,試圖解決你的問題,希望現在適合你。 –

+0

當我刪除'root to:'人們不會被重定向到'/ admin',我不希望我的用戶自己知道。我的根有一個api的入口,它使用了守望者而不是設計。 –

相關問題