- Windows XP or Server 2003 running IIS 5.1 or IIS 6.0 - Ruby Version 185-21 - Rails-1.0.0 - Rake-0.6.2 - ActiveRecord-1.13.2 - ActiveSupport-1.2.5 - ActionWebService-1.0.0 - ActionPack-1.11.2 - ActionMailer-1.1.5Ruby on Rails - Fast-CGI for IIS - Manual Configuration
The Fast-CGI ISAPI filter uses values stored in the registry. These values can be modified manually. If you change the values, don't forget to restart IIS. Their location is: HKEY_LOCAL_MACHINE\Software\FastCGI\.fcgi\
This file needs to be saved in your application's lib folder. ex. "#{RAILS_ROOT}/lib/action_controller_request_ext.rb"
module ActionController class AbstractRequest # override to fix IIS issues def request_uri if uri = env['REQUEST_URI'] (%r{^\w+\://[^/]+(/.*|$)$} =~ uri) ? $1 : uri # Remove domain, which webrick puts into the request_uri. else # REQUEST_URI is blank under IIS - get this from PATH_INFO and SCRIPT_NAME # remove the script file name from the URI uri = env['PATH_INFO'] uri = uri.sub("#{env['SCRIPT_NAME']}", "") unless env['SCRIPT_NAME'].nil? # replace the isapi rewrite query string with the original path and query (opnq) unless( opnq = env["QUERY_STRING"]).nil? || opnq.empty? env["QUERY_STRING"] = opnq.sub("?","&") # overwrite the invalid query string uri << opnq.sub("opnq=", "") end uri end end end end
This tells rails to use your version of request_uri method. If you plan on deploying your application to other servers or update the rails gem frequently, this keeps you from having to always patch the rails code.
This file must be saved into your application's lib folder. ex. "#{RAILS_ROOT}/lib/active_record_sql_server_connection_adapter_ext.rb"
module ActiveRecord class Base def self.sqlserver_connection(config) #:nodoc: require_library_or_gem 'dbi' unless self.class.const_defined?(:DBI) config = config.symbolize_keys mode = config[:mode] ? config[:mode].to_s.upcase : 'ADO' username = config[:username] ? config[:username].to_s : 'sa' password = config[:password] ? config[:password].to_s : '' if mode == "ODBC" raise ArgumentError, "Missing DSN. Argument ':dsn' must be set in order for this adapter to work." unless config.has_key?(:dsn) dsn = config[:dsn] driver_url = "DBI:ODBC:#{dsn}" else raise ArgumentError, "Missing Database. Argument ':database' must be set in order for this adapter to work." unless config.has_key?(:database) database = config[:database] host = config[:host] ? config[:host].to_s : 'localhost' if username.empty? or username == 'SSPI' driver_url = "DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};Integrated Security=SSPI;" else driver_url = "DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};User Id=#{username};Password=#{password};" end end conn = DBI.connect(driver_url, username, password) conn["AutoCommit"] = true ConnectionAdapters::SQLServerAdapter.new(conn, logger, [driver_url, username, password]) end end end
This tells rails to use your version of self.sqlserver_connection method. If you plan on deploying your application to other servers or update the rails gem frequently, this keeps you from having to always patch the rails code.
If using Windows Authentication, specify 'SSPI' for username field, password will be ignored. To use SQL Authentication, simply specify the proper credentials for your application to authenticate.
If using Windows Authentication and IIS, you must grant the 'NT AUTHORITY\NETWORK SERVICE' account access to your database. If using Apache2, whichever account you are running the apache.exe service under, you must grant it access to the database.
class ApplicationController < ActionController::Base protected def require_valid_user username, password = parse_authentication_headers # put your custom authentication code here (something like the following): user = User.authenticate(username, password) unless user prompt_for_username_and_password return false end end private def parse_authentication_headers # extract authorization credentials if request.env.has_key? 'HTTP_X_HTTP_AUTHORIZATION' # this is custom authentication header (FCGI under IIS) authdata = request.env['HTTP_X_HTTP_AUTHORIZATION'].to_s.split elsif request.env.has_key? 'X-HTTP_AUTHORIZATION' # try to get it where mod_rewrite might have put it (APACHE) authdata = request.env['X-HTTP_AUTHORIZATION'].to_s.split elsif request.env.has_key? 'Authorization' # for Apache/mod_fastcgi with -pass-header Authorization authdata = request.env['Authorization'].to_s.split elsif request.env.has_key? 'HTTP_AUTHORIZATION' # this is the regular location authdata = request.env['HTTP_AUTHORIZATION'].to_s.split end if authdata and authdata[0] == 'Basic' user,pass = Base64.decode64(authdata[1]).split(':')[0..1] end return [user,pass] end def prompt_for_username_and_password response.headers['Status'] = '401 Unauthorized' response.headers['WWW-Authenticate'] = 'Basic realm="MyRailsServer"' end end