How to authenticate users using rubycas-server with multi-field?

260 views Asked by At

I used rubycas-server to build an sso systems, using devise to do the user's system, but now my question is, rubycas-server only one field like 'email' , I want to use 'email' / 'tel' / 'nickname' for user login. no more info in wiki

authenticator:
 class: CASServer::Authenticators::SQLBcrypt
 database:
   adapter: mysql2
   database: xxxx
   username: root
   password: xxxx
   host: localhost
 user_table: users
 username_column: email # tel/nickname
 password_column: encrypted_password

sorry about my poor English! help me, thanks very much!

2

There are 2 answers

0
rainstop3 On BEST ANSWER

Modify the following code in rubycas-server/lib/casserver/authenticators/sql_bcrypt.rb

  def matching_users
    results = user_model.find(:all, :conditions => ["#{username_column} = ?", @username])
    results.select { |user| BCrypt::Password.new(user.send(password_column.to_sym)) == @password }
  end

to

  def matching_users
    if username_column.include?(',')
      columns = username_column.split(',')
      sql = ''
      conditions = []
      columns.each do |field|
        if sql.length != 0
          sql += ' or '
        end
        sql += "#{field} = ?"
        conditions << @username
      end
      conditions.unshift(sql)
    else
      conditions = ["#{username_column} = ?", @username]
    end
    results = user_model.find(:all, :conditions => conditions)
    results.select { |user| BCrypt::Password.new(user.send(password_column.to_sym)) == @password }
  end

then u can use mutli-fieds in config.yml like this:

authenticator:
 class: CASServer::Authenticators::SQLBcrypt
 database:
   adapter: mysql2
   database: test
   username: root
   password: map
   host: localhost
 user_table: users
 username_column: email,nickname,tel
 password_column: encrypted_password
1
blelump On

I'm affraid it woulnd't be possible. As can be seen in the official repository, this authenticator just matches given column name with user name:

  def matching_users
    results = user_model.find(:all, :conditions => ["#{username_column} = ?", @username])
    results.select { |user| BCrypt::Password.new(user.send(password_column.to_sym)) == @password }
  end

For your case the best idea would be to write custom authenticator that matches email/tel/nickname. This is however very tough login name though, consider some more user friendly.