| 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