Ruby on RailsでApacheの認証情報を取得する

Kerberosを使ったsingle sign onで mod_auth_kerbを使って認証する方法について説明しました。 ここでは、Apacheで認証したuserをRuby on Railsで取得してみます。

認証情報

Apacheのhttpd.confに以下のような記述をしてあるとします。

...
<Location "/myapp/">
  require valid-user
  AuthName "My Application Login"
  AuthType Kerberos
  KrbMethodNegotiate on
  KrbAuthRealms WORK.HANABUSA.NET
  Krb5Keytab /etc/httpd/httpd.keytab

  ProxyRequests     Off
  ProxyPreserveHost On
  ProxyPass http://localhost:3000/myapp
  ProxyPassReverse http://localhost:3000/myapp
  RequestHeader set X-Forwarded-User %{REMOTE_USER}s
  RequestHeader set X-Forwarded-SSL  on
</Location>

TCP 3000番で走っているapplication serverには、 X-Forwarded-UserというHTTP header経由でuser情報が渡されます。 Railsではrequest objectからHTTP headerを取得できるため、以下のような Ruby codeで認証情報を取得できます。

remote_user = request.headers['X-Forwarded-User']

LDAPでuser情報を取得

mod_auth_kerbで認証すると account@domain という形式で user が渡されます。 これをLDAPの domain component と account に変換して、LDAPからuser情報を取得してみます。 LDAPから情報を取得するには、Rubyのnet-ldapを使います。

$ gem install net-ldap 

でinstallできます。 Active Directoryであれば、accountがLDAPのsAMAccountNameと、 domainがLDAPのDCとそれぞれ対応しますので、以下のようなRuby codeで Kerberos の user principal name から LDAP の情報を引くことができます。

  require 'net/ldap'

  def get_user_info
    result = [ nil, nil, nil ]
    upn = request.headers['X-Forwarded-User']

    if upn then
      basedn, account = upn2ldap(upn)

      ldap = Net::LDAP.new( :host=>'localhost', :port=>389 )
      filter = Net::LDAP::Filter.eq('sAMAccountName', account)
      attrs  = [ :cn, :mail ]
      ldap.search( :base=>basedn, :filter=>filter, :attributes=>attrs) { |entry|
        result = [ account, entry[:cn][0], entry[:mail][0] ]
      }
    end

    result
  end

  #
  # 'myuser@WORK.HANABUSA.NET' to
  # 'DC=WORK,DC=HANABUSA,DC=NET', 'myuser'
  #
  def upn2ldap(upn)
    account, domain = upn.split('@', 2)

    if domain then
      # 'WORK.HANABUSA.NET' => 'DC=WORK,DC=HANABUSA,DC=NET'
      dcs = domain.split('.')
      dcs.map! { |dc| 'DC='+dc } 
      dn = dcs.join(',')
    else
      dn = nil
    end

    # returns dn and account
    [ dn, account ]
  end

更新 : 2014-08-01
ご意見、ご感想は、花房 真広 <webmaster@hanabusa.net>まで。メールする前にtop pageの注意書を読んでください。