Class | CASServer::Authenticators::SQL |
In: |
lib/casserver/authenticators/sql.rb
|
Parent: | CASServer::Authenticators::Base |
Authenticates against a plain SQL table.
This assumes that all of your users are stored in a table that has a ‘username’ column and a ‘password’ column. When the user logs in, CAS conects to the database and looks for a matching username/password in the users table. If a matching username and password is found, authentication is successful.
Any database backend supported by ActiveRecord can be used.
Config example:
authenticator: class: CASServer::Authenticators::SQL database: adapter: mysql database: some_database_with_users_table username: root password: server: localhost user_table: users username_column: username password_column: password
When replying to a CAS client‘s validation request, the server will normally provide the client with the authenticated user‘s username. However it is now possible for the server to provide the client with additional attributes. You can configure the SQL authenticator to provide data from additional columns in the users table by listing the names of the columns under the ‘extra_attributes’ option. Note though that this functionality is experimental. It should work with RubyCAS-Client, but may or may not work with other CAS clients.
For example, with this configuration, the ‘full_name’ and ‘access_level’ columns will be provided to your CAS clients along with the username:
authenticator: class: CASServer::Authenticators::SQL database: adapter: mysql database: some_database_with_users_table user_table: users username_column: username password_column: password ignore_type_column: true # indicates if you want to ignore Single Table Inheritance 'type' field extra_attributes: full_name, access_level
# File lib/casserver/authenticators/sql.rb, line 57 57: def self.setup(options) 58: raise CASServer::AuthenticatorError, "Invalid authenticator configuration!" unless options[:database] 59: 60: user_model_name = "CASUser_#{options[:auth_index]}" 61: $LOG.debug "CREATING USER MODEL #{user_model_name}" 62: 63: class_eval %{ 64: class #{user_model_name} < ActiveRecord::Base 65: end 66: } 67: 68: @user_model = const_get(user_model_name) 69: @user_model.establish_connection(options[:database]) 70: @user_model.set_table_name(options[:user_table] || 'users') 71: @user_model.inheritance_column = 'no_inheritance_column' if options[:ignore_type_column] 72: end
# File lib/casserver/authenticators/sql.rb, line 78 78: def validate(credentials) 79: read_standard_credentials(credentials) 80: raise_if_not_configured 81: 82: user_model = self.class.user_model 83: 84: username_column = @options[:username_column] || 'username' 85: password_column = @options[:password_column] || 'password' 86: 87: $LOG.debug "#{self.class}: [#{user_model}] " + "Connection pool size: #{user_model.connection_pool.instance_variable_get(:@checked_out).length}/#{user_model.connection_pool.instance_variable_get(:@connections).length}" 88: results = user_model.find(:all, :conditions => ["#{username_column} = ? AND #{password_column} = ?", @username, @password]) 89: user_model.connection_pool.checkin(user_model.connection) 90: 91: if results.size > 0 92: $LOG.warn("#{self.class}: Multiple matches found for user #{@username.inspect}") if results.size > 1 93: 94: unless @options[:extra_attributes].blank? 95: if results.size > 1 96: $LOG.warn("#{self.class}: Unable to extract extra_attributes because multiple matches were found for #{@username.inspect}") 97: else 98: user = results.first 99: 100: extract_extra(user) 101: log_extra 102: end 103: end 104: 105: return true 106: else 107: return false 108: end 109: end
# File lib/casserver/authenticators/sql.rb, line 119 119: def extract_extra user 120: @extra_attributes = {} 121: extra_attributes_to_extract.each do |col| 122: @extra_attributes[col] = user.send(col) 123: end 124: end
# File lib/casserver/authenticators/sql.rb, line 126 126: def log_extra 127: if @extra_attributes.empty? 128: $LOG.warn("#{self.class}: Did not read any extra_attributes for user #{@username.inspect} even though an :extra_attributes option was provided.") 129: else 130: $LOG.debug("#{self.class}: Read the following extra_attributes for user #{@username.inspect}: #{@extra_attributes.inspect}") 131: end 132: end