3

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!

Rubyrider
  • 3,567
  • 1
  • 28
  • 34
scottxu
  • 913
  • 1
  • 7
  • 20
  • 1
    I would say, clone the repo, write your own wrapper and make it happening inside this application. If possible try to create a pull request, if you want to help the community with your features. I went through their systems, and I couldn't find any solution for multiple login keys. I may take a look and if possible I will try write a wrapper for you. But I am afraid if I have that much time! – Rubyrider Nov 18 '14 at 18:58

2 Answers2

4

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.

blelump
  • 3,233
  • 1
  • 16
  • 20
  • I was thinking the same thing. Perhaps, finding the user can be made inside the client app before sending to the SSO side. I believe that can make more sense. This type of thing should be handled in the client side only. The SSO part should only care about the authentication. Your answer should deserve the right answer from my understandings. – Rubyrider Nov 18 '14 at 19:01
1

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
rainstop3
  • 1,408
  • 11
  • 13