diff --git a/lib/authlogic_x509/session.rb b/lib/authlogic_x509/session.rb
index eae8e19..599c8e4 100644
--- a/lib/authlogic_x509/session.rb
+++ b/lib/authlogic_x509/session.rb
@@ -1,5 +1,3 @@
-require 'openssl'
-
module AuthlogicX509
module Session
# Add a simple openid_identifier attribute and some validations for the field.
@@ -12,23 +10,23 @@ def self.included(klass)
module Config
# Once X509 authentication has succeeded we need to find the user in the database. By default this just calls the
- # find_with_x509_login method provided by ActiveRecord. If you have a more advanced set up and need to find users
+ # find_by_x509_subject_dn method provided by ActiveRecord. If you have a more advanced set up and need to find users
# differently specify your own method and define your logic in there.
#
# For example, if you allow users to store multiple x509 subject DNs with their account, you might do something like:
#
# class User < ActiveRecord::Base
- # def self.find_with_x509_login(login_hash)
- # first(:conditions => ["#{X509Login.table_name}.subject_dn = ? and #{X509Login.table_name}.issuer_dn = ?", login_hash[:subject_dn], login_hash[:issuer_dn]], :join => :x509_logins)
+ # def self.find_by_x509_subject_dn(login)
+ # first(:conditions => ["#{X509Login.table_name}.login = ?", login], :join => :x509_logins)
# end
# end
#
- # * Default: :find_with_x509_login
+ # * Default: :find_by_x509_subject_dn
# * Accepts: Symbol
- def find_with_x509_login_method(value = nil)
- rw_config(:find_with_x509_login_method, value, :find_with_x509_login)
+ def find_by_x509_login_method(value = nil)
+ rw_config(:find_by_x509_login_method, value, :find_by_x509_login)
end
- alias_method :find_with_x509_login_method=, :find_with_x509_login_method
+ alias_method :find_by_x509_login_method=, :find_by_x509_login_method
end
@@ -36,74 +34,68 @@ module Methods
def self.included(klass)
klass.class_eval do
attr_accessor :x509_login
- attr_accessor :x509_subject_dn
attr_accessor :x509_issuer_dn
- attr_accessor :x509_client_cert
+ attr_accessor :x509_subject_dn
validate :validate_by_x509, :if => :authenticating_with_x509?
end
end
-
- # Hooks into credentials so that you can pass an :x509_login key.
- def credentials
- if authenticating_with_x509?
- details = {}
- details[:x509_subject_dn] = self.x509_subject_dn
- details[:x509_issuer_dn] = self.x509_issuer_dn
- details
- else
- super
- end
- end
+ # Hooks into credentials so that you can pass an :x509_login key.
def credentials=(value)
super
values = value.is_a?(Array) ? value : [value]
hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
if !hash.nil?
self.x509_login = hash[:x509_login] if hash.key?(:x509_login)
- self.x509_client_cert = hash[:x509_client_cert] if hash.key?(:x509_client_cert)
end
end
-
+
private
def authenticating_with_x509?
- x509_login
+ attempted_record.nil? && errors.empty? && x509_login
end
def validate_by_x509
- parse_x509_login
- if self.x509_subject_dn || self.x509_issuer_dn
- self.attempted_record = search_for_record(find_with_x509_login_method, {:subject_dn=>x509_subject_dn,:issuer_dn=>x509_issuer_dn})
- errors.add(:x509_login, I18n.t('error_messages.x509_login_user_not_found', :default => "does not exist")) if attempted_record.blank?
+
+ if controller.local_request?
+ self.x509_subject_dn = "/CN=Local Request"
+ self.x509_issuer_dn = "/CN=Local Issuer"
+ elsif controller.request.env['SSL_CLIENT_S_DN'] =~ /CN/
+ self.x509_subject_dn = controller.request.env['SSL_CLIENT_S_DN']
+ self.x509_issuer_dn = controller.request.env['SSL_CLIENT_I_DN']
+ elsif controller.request.env['REDIRECT_SSL_CLIENT_S_DN'] =~ /CN/
+ self.x509_subject_dn = controller.request.env['REDIRECT_SSL_CLIENT_S_DN']
+ self.x509_issuer_dn = controller.request.env['REDIRECT_SSL_CLIENT_I_DN']
+ elsif controller.request.env['HTTP_REDIRECT_SSL_CLIENT_S_DN'] =~ /CN/
+ self.x509_subject_dn = controller.request.env['HTTP_REDIRECT_SSL_CLIENT_S_DN']
+ self.x509_issuer_dn = controller.request.env['HTTP_REDIRECT_SSL_CLIENT_I_DN']
+ end
+
+ if self.x509_subject_dn && self.x509_issuer_dn
+ controller.logger.info "start"
+ self.attempted_record = klass.send(find_by_x509_login_method, x509_subject_dn, x509_issuer_dn)
+ controller.logger.info "stop"
+ errors.add(:x509_login, I18n.t('error_messages.x509_login_not_found', :default => "does not exist")) if attempted_record.blank?
else
- errors.add_to_base("User not found")
+ errors.add_to_base("Subject DN not found")
end
end
- def find_with_x509_login_method
- self.class.find_with_x509_login_method
+ def find_by_x509_login_method
+ self.class.find_by_x509_login_method
end
- def parse_x509_login
- get_subject_dn
- get_issuer_dn
- end
-
- def get_subject_dn
- if controller.local_request?
- self.x509_subject_dn = "/CN=Local Request"
- elsif cert = OpenSSL::X509::Certificate.new(x509_client_cert)
- self.x509_subject_dn = cert.subject.to_s
- end
- end
-
- def get_issuer_dn
- if controller.local_request?
- self.x509_issuer_dn = "/CN=Local Request Issuer"
- elsif cert = OpenSSL::X509::Certificate.new(x509_client_cert)
- self.x509_issuer_dn = cert.issuer.to_s
- end
- end
+ def x509_subject_dn
+ self.class.x509_subject_dn
+ end
+
+ def x509_issuer_dn
+ self.class.x509_issuer_dn
+ end
+
+ def x509_login
+ self.class.x509_login
+ end
end
end
end
\ No newline at end of file