Rubycas-serverとdeviseでCAS認証


複数のRailsアプリケーションでの認証を共通化させるためにCAS認証サーバを立てる。Rubycas-serverを導入しました。
利用させていただいたのは以下で、それぞれGithubに上がっている。

rubycas-server
devise
devise_cas_authenticatable

セットアップのためにやるべきことは、すべてそれぞれのGithubサイトに書かれている。

ここでは、それらをやってみて最初のうちよくわからなかった部分について書きます。

サーバー側

Authenticator に何を使うべきなのか?
— 同じサーバーにdeviseを使ったアプリを置く

rubycas-server の設定では必ず1つ usersテーブルを持つAuthenticator を指定しなければなりません。そもそも最初はこれが何を意味するのかわかりませんでした。

とりあえず、何かuser管理ができるアプリケーションを別途作って、そのusersテーブルを指定すればいいということだと僕は解釈しました。手短に使えるようcasサーバーとなる同じサーバー上に管理用アプリを立てて、使い慣れたdeviseを導入。

deviseを使うとして、まあusernameの追加は必要。で暗号複合化は?
— SQLBcryptを指定する

deviseは基本email認証なのでusernameを追加しなければならない。まあこれは普通のことなのでやる。full nameやaccess levelも追加。以下が参考になる。
deviseでログインにemailではなくusernameを使用する

deviseはBcryptであるらしい。authenticator の SQLEncrypted を SQLBcrypt にすることで対応できる。助かる。

以上からcongig.yml での指定は以下のようになる。
password_column は encrypted_password だ。
email, fullname, accesslevel をクライアントに渡すためにextra_attributes: を指定する。

authenticator:
  class: CASServer::Authenticators::SQLBcrypt
  database:
    adapter: postgresql 
    database: exampledb 
    username: exampledbuser
    password: xxxxx
  user_table: users
  username_column: username
  password_column: encrypted_password 
  extra_attributes: email, fullname, accesslevel

ところで、rubycas-server/locales/jp.yml は ja.yml にしなければならない。これで日本語が表示された。

クライアント側

devise_cas_authenticatable を導入すれば、簡単にrailsアプリケーションにcasクライアントが組み込める。Rails4でも使えている。インストール方法は、githubページに全てかかれている。

create table users?
— クライアントにもusersテーブルは要る

githubページにusersテーブルを作ることが書かれている。CASサーバーを見に行くのだから不要では?と思うが、やはり必要なようだ。また、email, fullname, accesslevel の追加をしているので、これらのフィールドも追加しなければならない。

create_table :users do |t|
  t.string :username, :null => false
  t.string :fullname
  t.string :email
  t.integer :accesslevel
end

user.rbにも同じように追加

class User < ActiveRecord::Base
  devise :cas_authenticatable
  def cas_extra_attributes=(extra_attributes)
    extra_attributes.each do |name, value|
      case name.to_sym
      when :fullname
        self.fullname = value
      when :email
        self.email = value
      when :accesslevel
        self.accesslevel = value
      end
    end
  end
end

試しにクライアント側アプリケーションで users/sign_in を指定するとCASサーバーのログイン画面にリダイレクトされ、ログインするとクライアント側アプリケーションに戻って来て、current_user.fullname や current_user.accesslevel が取得できる。

なお、 クライアント側のusersテーブルにはusernameや作った項目の全てにデータが保存されている(コピーだ)。これは、これでいいのだろうか?少し疑問が残るところ。もしかしたら保存させない方法もあるのかも知れない。知っている方がいたら教えてください。

全体像を図に書いてみた。
fig1