FuelPHPでLDAP認証を実現する

はじめまして。「おもしろ関西人」です。

どれだけおもしろいかは実際にお会いしてからのお楽しみ。
業務ではメディア事業部のエンジニアとして自社メディアの開発を行っています。

FuelPHPLDAP認証を実現する

社内向けシステムが複数ある場合、ユーザ(社員)のアカウントを
システムごとに持っていると管理が大変です。

・ユーザ情報を一元管理して各社内システムで利用したい
・どの社内システムでも同じユーザ名、パスワードでログインしたい

そんな要望がある場合、LDAPを利用することが選択肢の一つになります。

今回はPHPフレームワークの1つであるFuelPHPLDAP認証機能を追加する方法を紹介します。

LDAPとは?

LDAP(Lightweight Directory Access Protocol)とは、ディレクトリサービスに アクセスするためのプロトコルです。

ディレクトリサービスとは、ネットワークを利用するユーザ名やマシン名などの
様々な情報を管理するためのサービスです。
LDAPはデータの変更、削除よりも検索に最適化されたプロトコルであり、
ディレクトリサービスによってユーザ,パスワード情報を一元管理し、
複数の端末から同じユーザでアクセスしたい場合などに使われます。

ldap
LDAPプロトコルの実装としては、
オープンソースOpenLDAPの他、
Microsoft社のActiveDirectoryなどが代表的です。

使用するもの

LDAPサーバ

ActiveDirectoryが動作しているサーバを想定しています。

fuel-ldapauth

GitHub: https://github.com/sharkpp/fuel-ldapauth

FuelPHPの認証ドライバSimpleAuthのログイン認証部分をLDAP用に書き換えたパッケージです。
LDAPサーバに対して認証するだけであればPHPLDAP関数を使えば可能ですが、
今回はセッションやユーザ権限の管理も行うためこちらのパッケージを利用します。

fuel-ldapauth導入

手順

  1. ldapauthパッケージをPKGPATHに配置

  2. 認証用テーブル初期化

$ php oil refine migrate --packages=ldapauth

以下のようなテーブルができます。
SimpleAuthドライバで利用するテーブルとの違いはpasswordカラムが無い点ですね。

mysql> desc users;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| id             | int(11)      | NO   | PRI | NULL    | auto_increment |
| username       | varchar(50)  | NO   |     | NULL    |                |
| group          | int(11)      | NO   |     | 1       |                |
| email          | varchar(255) | NO   |     | NULL    |                |
| last_login     | varchar(25)  | NO   |     | NULL    |                |
| login_hash     | varchar(255) | NO   |     | NULL    |                |
| profile_fields | text         | NO   |     | NULL    |                |
| created_at     | int(11)      | NO   |     | 0       |                |
| updated_at     | int(11)      | NO   |     | 0       |                |
+----------------+--------------+------+-----+---------+----------------+
  1. APPPATH/config/config.phpに利用するパッケージを追加
'always_load'  => array(
    'packages'  => array(
        'auth',
        'ldapauth',
    ),
),
  1. APPPATH/config/auth.phpで認証ドライバをLdapAuthに変更
'driver' => 'LdapAuth',
  1. APPPATH/config/ldapauth.phpLDAP認証情報を記述
  • host
  • username
  • password
  • basedn

最低限これらの項目が設定されていれば動作します。
認証テーブル名、カラム名を変える場合はこのファイルを編集してください。

動作確認

if(Auth::login($username, $password)){
    // ログイン成功
} else {
    // ログイン失敗
}

これでLDAPを使ったログイン認証ができるようになりました。

ActiveDiredtoryから取得するユーザ属性を増やしたい

ActiveDirectoryにはユーザ認証に必要なもの以外にも
ユーザの属性が登録されている場合が多いです。
LDAPを使えばこれらのユーザ属性データも取得することができます。

ldap2

せっかくActiveDirectoryと連携するならこれらの属性データも使いたいですよね。
認証に関係のないデータは認証用テーブルの
profile_fieldsカラムに保存しましょう。

fuel-ldapauthパッケージではfirstnameとlastnameのユーザ属性のみをprofile_fieldsに
保存しているため、保存する属性を増やすにはパッケージを修正する必要があります。

主な修正は2箇所(※日本語のユーザ名=displayNameを追加する場合の例)
Impl_Auth_Login_Ldapauth#get_user_dn()

// ldapsearchのfilter指定部分
foreach(array('account', 'email', 'firstname', 'lastname', 'displayname') as $filter_item)
{
    if( self::g($filter_item) ) {
        $filter[] = self::g($filter_item);
    }
}

Stateholder_Db#update()

// profile_fieldsカラムへの格納データ定義部分
$profile_fields = @unserialize($stored->get($this->profile_fields));
isset($user_info['firstname']) and $profile_fields[$this->firstname_field] = $user_info['firstname'];
isset($user_info['lastname'])  and $profile_fields[$this->lastname_field]  = $user_info['lastname'];
isset($user_info['displayname'])  and $profile_fields[$this->displayname_field]  = $user_info['displayname'];

ユーザ権限の管理がしたい

ActiveDirectoryから部署や役職の属性が取得できたなら
今度はその属性で権限の管理がしたくなるかと思います。

fuel-ldapauthのグループドライバ、ACLドライバは
SimpleAuthパッケージのドライバを利用しています。
そのため、SimpleAuthと同じく認証用テーブルのgroupカラムで
ユーザのグループ設定が可能であり、グループごとのロールも設定できます。

ユーザの属性データをgroupカラムと紐付ける処理を実装すれば
ActiveDirectoryの属性による権限管理が可能となります。

おわりに

今回のブログでは、FuelPHPLDAP認証を実現するための
fuel-ldapauthパッケージの導入方法について書かせていただきました。
社内システム開発の際に参考にしていただければ嬉しいです。