Edited at

devise で ActiveDirectory 認証

More than 3 years have passed since last update.


前提条件

以下の環境にて動作確認が行えました。


開発環境


  • Mac OS X Yosemite (10.10.3)

  • Bundler version 1.10.5

  • rbenv 0.4.0

  • ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14]

  • mysql Ver 14.14 Distrib 5.6.24, for osx10.10 (x86_64)


Rails


  • rails (4.2.3)

  • net-ldap (0.11)

  • devise (3.5.1)

  • devise_ldap_authenticatable (0.8.5)


Active Directory


  • Windows Server 2012


devise のインストールと設定


Gemfile 追記


Gemfile

gem 'devise'

gem 'devise_ldap_authenticatable'


インストール

$ bundle install -j4 --path=vendor/bundle

$ rails g devise:install
$ rails g devise User
$ rails g devise_ldap_authenticatable:install


User モデル修正


app/models/user.rb

class User < ActiveRecord::Base

devise :ldap_authenticatable, :rememberable, :trackable
end


マイグレーションファイル修正

デフォルトの email ログインを username ログインに修正。


db/migrate/YYYYMMDDhhmmss_devise_create_user.rb

class DeviseCreateUsers < ActiveRecord::Migration

def change
create_table(:users) do |t|
## LDAP authenticatable
t.string :username, null: false, default: "", unique: true
## Database authenticatable
# t.string :email, null: false, default: ""
# t.string :encrypted_password, null: false, default: ""

## Recoverable
# t.string :reset_password_token
# t.datetime :reset_password_sent_at

## Rememberable
t.datetime :remember_created_at

## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip

## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable

## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at

t.timestamps null: false
end

add_index :users, :username, unique: true
# add_index :users, :email, unique: true
# add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end



マイグレーション

$ rake db:migrate


devise 初期設定

修正箇所のみ。


config/initializers/devise.rb

config.ldap_logger = true

config.ldap_create_user = true
config.ldap_update_password = false
config.ldap_use_admin_to_bind = true
config.authentication_keys = [ :username ]


LDAP 設定


config/ldap.yml

development:

host: <Domain Controller を指定>
port: 389
attribute: sAMAccountName
base: dc=xxx,dc=xx,dc=xx
admin_user: "<bind user>"
admin_password: "bind user password"
ssl: false

admin_useradmin_password"" で括る必要があります。

デフォルトだと "" がありませんが、その状態だと以下のエラーが発生してかなりハマりました。。

Net::LDAP::LdapError (Invalid binding information)


ログイン用 view 作成

$ rails g devise:views


ログイン画面修正



  • :email => :username


  • email_field => text_field


app/views/devise/session/new.html.erb

<h2>Log in</h2>

<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username, autofocus: true %>
</div>

<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>

<% if devise_mapping.rememberable? -%>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end -%>

<div class="actions">
<%= f.submit "Log in" %>
</div>
<% end %>

<%= render "devise/shared/links" %>



ルーティング


設定


config/routes.rb

devise_for :users, only: [:sessions]



確認

rake routes


全ページ認証設定


app/controllers/application_controller.rb

before_action :authenticate_user!



ログアウトリンク設定

<%= link_to "Logout", destroy_user_session_path, method: :delete, :class => 'navbar-link' %>