Authentication Questions

Hi All... Apologies in advance if this isn't the right group (but I couldn't find a rails specific one) anyway -

    I think I am having a problem passing data around in my MVC.

I have a view that looks has this in the middle:

<code>                    <%= form_tag :controller => "login", :action => "login" %>                        <tr>                            <td>DOMAIN\Username:</td>                            <td><%= text_field(:login, :username) %></td>                         </tr>                                                 <tr>                            <td>Password:</td>                            <td><%= password_field(:login, :password) %></td>                         </tr>                                                 <tr align = "left">                             <td /><td><input type="submit" value="Submit"></td>                         </tr>                    <%= end_form_tag %> </code>

and here is my login_controller.rb

<code> class LoginController < ApplicationController   before_filter :authorize, :except => [:login, :logout]

  def login     if request.get?       session[:username] = nil     else           #get the username and password from the array           username = params[:login][:username]           password = params[:login][:password]       # Split username on domain and alias           split_username = params[:user][:name].split('\\',2)       if split_username.length != 2         flash[:notice] = "You did not enter a properly formatted domain and username"         redirect_to :action => 'login'       else         # Authenticate username and password         domain = split_username[0]         username = split_username[1]         password = params[:user][:password]         if authenticate domain, username, password           # User has been authenticated           session[:username] = username         else           flash[:notice] = "Incorrect username or password"           redirect_to :action => 'login'         end       end     end   end

  def logout     session[:username] = nil   end

  require 'dl/win32'   LOGON32_LOGON_NETWORK = 3   LOGON32_PROVIDER_DEFAULT = 0   BOOL_SUCCESS = 1   AdvApi32 = DL.dlopen("advapi32")   Kernel32 = DL.dlopen("kernel32")

  def authorize     redirect_to( :controller => 'login', :action => 'login' ) unless logged_in?   end

  def logged_in?     session[:username] != nil   end

  def authenticate(domain, username, password)     # Load the DLL functions     logon_user = AdvApi32['LogonUser', 'ISSSIIp']     close_handle = Kernel32['CloseHandle', 'IL']

    # Normalize username and domain     username = username.strip.downcase     domain = domain.strip.downcase

    # Authenticate user     ptoken = "\0" * 4     r,rs = logon_user.call(username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ptoken)     success = (r == BOOL_SUCCESS)

    # Close impersonation token     token = ptoken.unpack('L')[0]     close_handle.call(token)

    session[:username] = username     return success   end end </code>

At the top of my application.rb I have:

<code> class ApplicationController < ActionController::Base   protected     def authorize       #changed from cookie to session       unless session[:username]         @session[:return_to] = @request.request_uri         redirect_to :controller => "login"         return false       end     end end </code>

So the filtering works fine, when I try to access a protected page, it goes to my login.rhtml.

but when I login, It craps out on me with this:

<code>

NoMethodError in LoginController#login

You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occured while evaluating nil.

RAILS_ROOT: ./script/../config/.. Application Trace | Framework Trace | Full Trace

#{RAILS_ROOT}/app/controllers/login_controller.rb:12:in `login'

c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in `perform_action_without_filters' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:368:in `perform_action_without_benchmark' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue' c:/ruby/lib/ruby/1.8/benchmark.rb:293:in `measure' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/rescue.rb:82:in `perform_action' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in `process_without_filters' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:377:in `process_without_session_management_support' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/session_management.rb:117:in `process' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/dispatcher.rb:38:in `dispatch' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:115:in `handle_dispatch' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:81:in `service' c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:104:in `service' c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:65:in `run' c:/ruby/lib/ruby/1.8/webrick/server.rb:173:in `start_thread' c:/ruby/lib/ruby/1.8/webrick/server.rb:162:in `start_thread' c:/ruby/lib/ruby/1.8/webrick/server.rb:95:in `start' c:/ruby/lib/ruby/1.8/webrick/server.rb:92:in `start' c:/ruby/lib/ruby/1.8/webrick/server.rb:23:in `start' c:/ruby/lib/ruby/1.8/webrick/server.rb:82:in `start' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:67:in `dispatch' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/commands/servers/webrick.rb:59 c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `require' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/commands/server.rb:30 c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `require' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require' script/server:3

#{RAILS_ROOT}/app/controllers/login_controller.rb:12:in `login' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in `perform_action_without_filters' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:368:in `perform_action_without_benchmark' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue' c:/ruby/lib/ruby/1.8/benchmark.rb:293:in `measure' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/rescue.rb:82:in `perform_action' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in `process_without_filters' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:377:in `process_without_session_management_support' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/session_management.rb:117:in `process' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/dispatcher.rb:38:in `dispatch' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:115:in `handle_dispatch' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:81:in `service' c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:104:in `service' c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:65:in `run' c:/ruby/lib/ruby/1.8/webrick/server.rb:173:in `start_thread' c:/ruby/lib/ruby/1.8/webrick/server.rb:162:in `start_thread' c:/ruby/lib/ruby/1.8/webrick/server.rb:95:in `start' c:/ruby/lib/ruby/1.8/webrick/server.rb:92:in `start' c:/ruby/lib/ruby/1.8/webrick/server.rb:23:in `start' c:/ruby/lib/ruby/1.8/webrick/server.rb:82:in `start' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:67:in `dispatch' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/commands/servers/webrick.rb:59 c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `require' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/commands/server.rb:30 c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `require' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require' script/server:3

Request

Parameters: {"login"=>{"username"=>"test", "password"=>"test"}}

Show session dump

I don’t even know where to begin with this one… Make sure your form fields match what you’re trying to read in. I see you using this in your params list:

Read your error message and it basically tells you what you did wrong:

I'm writing my first production rails app. It needs to use authentication, and I'm wondering if my code is good/secure? If anyone would like to tell me what they think, it'd be great.

Thanks, jason

[code]

class ApplicationController < ActionController::Base   before_filter :authorize    def authorize     if @session[:user_id].nil?       flash[:notice] = "Please log in to continue"       redirect_to :controller => "account", :action => "login"     else       @logged_in_user = User.find(@session[:user_id])     end   end

end

class AccountController < ApplicationController   skip_before_filter :authorize    def login     if @request.post?       if possible_user = User.authenticate(@params[:login][:username], @params[:login][:password])         @session[:user_id] = possible_user.id         @session[:location] = possible_user.role.location_id         @session[:role_id] = possible_user.role.id         redirect_to(:controller => "application", :action => "index")       else         flash[:notice] = "Invalid username and/or password"          logger.info("INVALID LOGIN ATTEMPT -- Username: " +             @params[:login][:username])       end     end   end    def logout     reset_session     redirect_to(:controller => "account", :action => "login")   end

end

class User < ActiveRecord::Base    has_one :role    def self.authenticate(username, password)     this_user = find_by_username_and_password(username, encrypt(password), :include => 'role')     if this_user.nil? || this_user.role.nil?                       #Put log entry here, IF you can even do it in the model. Or do it in the controller       nil #Return Nil if no role is found for the user, or no user found for credentials     else       this_user #Return the user object for users with roles     end   end

  def self.encrypt(password)       [ password encryption code here.... ]   end end

instead of these 2 lines in your login_controller.rb           username = params[:login][:username]           password = params[:login][:password]

use this instead:

          username = session[:login][:username]           password = session[:login][:password]

try it and let me know how it works.

- B

aerospike wrote: