Problema con sesiones o cokies

Hola comunidad de rails, tengo un problema bastante trillado ni yo me
explico como es que sucede, el problema es el siguiente tengo un sitio
web ROR del cual necesito que se autentifiquen los usuarios y por lo
general los usuarios estan dentro de una red interna, pero la pagina
esta en la web, el problema viene que al loguearse un usuario ya todos
los usuarios estan logueados como el o que les bote del sistema sin
ninguna razon, sea cual fuese el navegador: lo he probado en IE6, IE7 y
Firefox 2, mediante firefox con el plugin firebug veo que la cookie de
la session se cambia a veces al momento de hacer cualquier request, pero
por lo que se no deberia de cambiar hasta cerrar el navegador, ademas
trate de usar las sessiones por cokie que vienen por defecto en rails
2.0 pero no se autentifica.

No creo que sea un problema de la red por que existe otro sitio
desarrollado en PHP del cual he monitoreado el cambio de la
cookie de la session pero este no cambia y trabaja normalmente, ademas
cualquier pagina Web que necesite autentificacion trabaja normalmente no
entiendo por que sucede este problema, El plugin que utilizo es REST-ful
Authentication ya lo use en otros trabajos y funciona correctamente.

Por favor ayudenme.

Carlos.

2008/4/14 Carlos R. [email protected]:

Hola comunidad de rails, tengo un problema bastante trillado ni yo me
explico como es que sucede, el problema es el siguiente tengo un sitio
web ROR del cual necesito que se autentifiquen los usuarios y por lo
general los usuarios estan dentro de una red interna, pero la pagina
esta en la web, el problema viene que al loguearse un usuario ya todos
los usuarios estan logueados como el o que les bote del sistema sin

¿Cómo estás manejando las sesiones por usuario y la
autenticación?¿Estás usando algún plugin o escribiste tu mismo el sistema?

PD: Un poco de puntuación y separación entre parrafos podría ayudar :slight_smile:

On Apr 14, 2008, at 18:15 , Carlos R. wrote:

Hola comunidad de rails, tengo un problema bastante trillado ni yo me
explico como es que sucede, el problema es el siguiente tengo un sitio
web ROR del cual necesito que se autentifiquen los usuarios y por lo
general los usuarios estan dentro de una red interna, pero la pagina
esta en la web, el problema viene que al loguearse un usuario ya todos
los usuarios estan logueados como el o que les bote del sistema sin
ninguna razon, sea cual fuese el navegador:

Estas vinculando la autenticacion con la IP de alguna manera por
casualidad?

– fxn

�C�mo est�s manejando las sesiones por usuario y la
autenticaci�n?�Est�s usando alg�n plugin o escribiste tu mismo el sistema?

Estoy manejando el plugin Restful authentication, y no estoy manejando
ninguna especie de manejo de IP de por medio.

Saludos.

On Apr 14, 2008, at 21:47 , Carlos R. wrote:

�C�mo est�s manejando las sesiones por usuario y la
autenticaci�n?�Est�s usando alg�n plugin o escribiste tu
mismo el sistema?

Estoy manejando el plugin Restful authentication, y no estoy manejando
ninguna especie de manejo de IP de por medio.

Puedes enviar los filtros relacionados con autenticacion, accion de
login, y metodos propios del usuario relevantes por favor?

Tiene que tratarse de un error de programacion en algun lugar. No del
plugin en principio, sino del codigo propio lo usa.

– fxn

Xavier N. wrote:

On Apr 14, 2008, at 21:47 , Carlos R. wrote:

�C�mo est�s manejando las sesiones por usuario y la
autenticaci�n?�Est�s usando alg�n plugin o escribiste tu
mismo el sistema?

Estoy manejando el plugin Restful authentication, y no estoy manejando
ninguna especie de manejo de IP de por medio.

Puedes enviar los filtros relacionados con autenticacion, accion de
login, y metodos propios del usuario relevantes por favor?

Tiene que tratarse de un error de programacion en algun lugar. No del
plugin en principio, sino del codigo propio lo usa.

– fxn

Bueno este es el controlador de las sessiones:

/app/controller/sessions_controller.rb
class SessionsController < ApplicationController
layout ‘login’
skip_before_filter :login_required
filter_parameter_logging :password

render new.rhtml

def new
respond_to do |format|
format.html # index.html.erb
format.js {}
end
end

def create
self.current_user = User.authenticate(params[:login],
params[:password])
if logged_in?
if params[:remember_me] == “1”
self.current_user.remember_me
cookies[:auth_token] = { :value =>
self.current_user.remember_token , :expires =>
self.current_user.remember_token_expires_at }
end
current_user.update_attribute(:total, current_user.total + 1)
redirect_back_or_default(‘/’)
flash[:notice] = “Usted ingreso satisfactoriamente”
else
flash[:notice] = “Usuario o contreseña incorrectos.”
redirect_to(params[:url])
end
end

def destroy
self.current_user.forget_me if logged_in?
cookies.delete :auth_token
reset_session
flash[:notice] = “Usted salio del Banco Temático
satisfactoriamente.”
redirect_back_or_default(‘/’)
end
end

El modelo del usuario.
/app/model/user.rb

require ‘digest/sha1’
class User < ActiveRecord::Base

---------------------------------------

The following code has been generated by role_requirement.

You may wish to modify it to suit your need

has_and_belongs_to_many :roles

has_role? simply needs to return true or false whether a user has a

role or not.

It may be a good idea to have “admin” roles return true always

def has_role?(role_in_question)
@_list ||= self.roles.collect(&:name)
return true if @_list.include?(“admin”)
(@_list.include?(role_in_question.to_s) )
end

---------------------------------------

Virtual attribute for the unencrypted password

attr_accessor :password

Cada usuario activado tiene una profesion registrada

belongs_to :profesion

validates_presence_of :login, :email, :message => “No puede estar
en blanco”
validates_presence_of :password, :if =>
:password_required?, :message => “Debe de introducir su
contraseña”
validates_presence_of :password_confirmation, :if =>
:password_required?, :message => “Debe de ser igual a la
contraseña”
validates_length_of :password, :within => 4…40, :if =>
:password_required?, :message => “Contraseña muy corta (minimo es
cuatro caracteres).”
validates_confirmation_of :password, :if =>
:password_required?
validates_length_of :login, :within => 3…40, :message => “Su
nombre de usuario, debe de ser mas grande (minimo es tres caracteres).”
validates_length_of :email, :within => 3…100, :message =>
“Correo electronico invalido.”
validates_uniqueness_of :login, :email, :case_sensitive => false,
:message => “Ya existe el registro.”
before_save :encrypt_password
before_create :make_activation_code

prevents a user from submitting a crafted form that bypasses

activation

anything else you want your user to change should be added here.

attr_accessible :login, :email, :password, :password_confirmation,
:nombre, :apellido, :profesion_id

Activates the user in the database.

def activate
@activated = true
self.activated_at = Time.now.utc
self.activation_code = nil
save(false)
end

def active?
# the existence of an activation code means they have not activated
yet
activation_code.nil?
end

Returns true if the user has just been activated.

def pending?
@activated
end

Authenticates a user by their login name and unencrypted password.

Returns the user or nil.
def self.authenticate(login, password)
u = find :first, :conditions => [‘login = ? and activated_at IS NOT
NULL’, login] # need to get the salt
u && u.authenticated?(password) ? u : nil
end

Encrypts some data with the salt.

def self.encrypt(password, salt)
Digest::SHA1.hexdigest(“–#{salt}–#{password}–”)
end

Encrypts the password with the user salt

def encrypt(password)
self.class.encrypt(password, salt)
end

def authenticated?(password)
crypted_password == encrypt(password)
end

def remember_token?
remember_token_expires_at && Time.now.utc <
remember_token_expires_at
end

These create and unset the fields required for remembering users

between browser closes
def remember_me
remember_me_for 2.weeks
end

def remember_me_for(time)
remember_me_until time.from_now.utc
end

def remember_me_until(time)
self.remember_token_expires_at = time
self.remember_token =
encrypt(“#{email}–#{remember_token_expires_at}”)
save(false)
end

def forget_me
self.remember_token_expires_at = nil
self.remember_token = nil
save(false)
end

protected
# before filter
def encrypt_password
return if password.blank?
self.salt =
Digest::SHA1.hexdigest(“–#{Time.now.to_s}–#{login}–”) if new_record?
self.crypted_password = encrypt(password)
end

def password_required?
  crypted_password.blank? || !password.blank?
end

def make_activation_code
  self.activation_code = Digest::SHA1.hexdigest( 

Time.now.to_s.split(//).sort_by {rand}.join )
end
end

/lib/authenticated_system.rb
module AuthenticatedSystem
protected
# Returns true or false if the user is logged in.
# Preloads @current_user with the user model if they’re logged in.
def logged_in?
current_user != :false
end

# Accesses the current user from the session.  Set it to :false if 

login fails
# so that future calls do not hit the database.
def current_user
@current_user ||= (login_from_session || login_from_basic_auth ||
login_from_cookie || :false)
end

# Store the given user id in the session.
def current_user=(new_user)
  session[:user_id] = (new_user.nil? || new_user.is_a?(Symbol)) ? 

nil : new_user.id
@current_user = new_user || :false
end

# Check if the user is authorized
#
# Override this method in your controllers if you want to restrict 

access
# to only a few actions or if you want to check if the user
# has the correct rights.
#
# Example:
#
# # only allow nonbobs
# def authorized?
# current_user.login != “bob”
# end
def authorized?
logged_in?
end

# Filter method to enforce a login requirement.
#
# To require logins for all actions, use this in your controllers:
#
#   before_filter :login_required
#
# To require logins for specific actions, use this in your 

controllers:
#
# before_filter :login_required, :only => [ :edit, :update ]
#
# To skip this in a subclassed controller:
#
# skip_before_filter :login_required
#
def login_required
authorized? || access_denied
end

# Redirect as appropriate when an access request fails.
#
# The default action is to redirect to the login screen.
#
# Override this method in your controllers if you want to have 

special
# behavior in case the user is not authorized
# to access the requested action. For example, a popup window might
# simply close itself.
def access_denied
respond_to do |format|
format.html do
store_location
flash[:notice] = “Debe de estar registrado para ingresar a
este recurso.
Regístrese es
fácil y rápido.”
redirect_to new_session_path
end
format.any do
request_http_basic_authentication ‘Web Password’
end
end
end

# Store the URI of the current request in the session.
#
# We can return to this location by calling 

#redirect_back_or_default.
def store_location
session[:return_to] = request.request_uri
end

# Redirect to the URI stored by the most recent store_location call 

or
# to the passed default.
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end

# Inclusion hook to make #current_user and #logged_in?
# available as ActionView helper methods.
def self.included(base)
  base.send :helper_method, :current_user, :logged_in?
end

# Called from #current_user.  First attempt to login by the user id 

stored in the session.
def login_from_session
self.current_user = User.find(session[:user_id]) if
session[:user_id]
end

# Called from #current_user.  Now, attempt to login by basic 

authentication information.
def login_from_basic_auth
authenticate_with_http_basic do |username, password|
self.current_user = User.authenticate(username, password)
end
end

# Called from #current_user.  Finaly, attempt to login by an 

expiring token in the cookie.
def login_from_cookie
user = cookies[:auth_token] &&
User.find_by_remember_token(cookies[:auth_token])
if user && user.remember_token?
user.remember_me
cookies[:auth_token] = { :value => user.remember_token, :expires
=> user.remember_token_expires_at }
self.current_user = user
end
end
end

/lib/role_requirement_system.rb

Main module for authentication.

Include this in ApplicationController to activate RoleRequirement

See RoleSecurityClassMethods for some methods it provides.

module RoleRequirementSystem
def self.included(klass)
klass.send :class_inheritable_array, :role_requirements
klass.send :include, RoleSecurityInstanceMethods
klass.send :extend, RoleSecurityClassMethods
klass.send :helper_method, :url_options_authenticate?

klass.send :role_requirements=, []

end

module RoleSecurityClassMethods

def reset_role_requirements!
  self.role_requirements.clear
end

# Add this to the top of your controller to require a role in order 

to access it.
# Example Usage:
#
# require_role “contractor”
# require_role “admin”, :only => :destroy # don’t allow
contractors to destroy
# require_role “admin”, :only => :update, :unless =>
"current_user.authorized_for_listing?(params[:id]) "
#
# Valid options
#
# * :only - Only require the role for the given actions
# * :except - Require the role for everything but
# * :if - a Proc or a string to evaluate. If it evaluates to true,
the role is required.
# * :unless - The inverse of :if
#
def require_role(roles, options = {})
options.assert_valid_keys(:if, :unless,
:for, :only,
:for_all_except, :except
)

  # only declare that before filter once
  unless (@before_filter_declared||=false)
    @before_filter_declared=true
    before_filter :check_roles
  end

  # convert to an array if it isn't already
  roles = [roles] unless Array===roles

  options[:only] ||= options[:for] if options[:for]
  options[:except] ||= options[:for_all_except] if 

options[:for_all_except]

  # convert any actions into symbols
  for key in [:only, :except]
    if options.has_key?(key)
      options[key] = [options[key]] unless Array === options[key]
      options[key] = options[key].compact.collect{|v| v.to_sym}
    end
  end

  self.role_requirements||=[]
  self.role_requirements << {:roles => roles, :options => options }
end

# This is the core of RoleRequirement.  Here is where it discerns if 

a user can access a controller or not./
def user_authorized_for?(user, params = {}, binding = self.binding)
return true unless Array===self.role_requirements
self.role_requirements.each{| role_requirement|
roles = role_requirement[:roles]
options = role_requirement[:options]
# do the options match the params?

    # check the action
    if options.has_key?(:only)
      next unless options[:only].include?( 

(params[:action]||“index”).to_sym )
end

    if options.has_key?(:except)
      next if options[:except].include?( 

(params[:action]||“index”).to_sym)
end

    if options.has_key?(:if)
      # execute the proc.  if the procedure returns false, we don't 

need to authenticate these roles
next unless ( String===options[:if] ? eval(options[:if],
binding) : options[:if].call(params) )
end

    if options.has_key?(:unless)
      # execute the proc.  if the procedure returns true, we don't 

need to authenticate these roles
next if ( String===options[:unless] ? eval(options[:unless],
binding) : options[:unless].call(params) )
end

    # check to see if they have one of the required roles
    passed = false
    roles.each { |role|
      passed = true if user.has_role?(role)
    } unless (user==:false || user==false)

    return false unless passed
  }

  return true
end

end

module RoleSecurityInstanceMethods
def self.included(klass)
raise “Because role_requirement extends acts_as_authenticated, You
must include AuthenticatedSystem first before including
RoleRequirementSystem!” unless
klass.included_modules.include?(AuthenticatedSystem)
end

def access_denied
  if logged_in?
    render :nothing => true, :status => 401
    return false
  else
    super
  end
end

def check_roles
  return access_denied unless 

self.class.user_authorized_for?(current_user, params, binding)

  true
end

protected
# receives a :controller, :action, and :params. Finds the given
controller and runs user_authorized_for? on it.
# This can be called in your views, and is for advanced users only.
If you are using :if / :unless eval expressions,
# then this may or may not work (eval strings use the current
binding to execute, not the binding of the target
# controller)
def url_options_authenticate?(params = {})
params = params.symbolize_keys
if params[:controller]
# find the controller class
klass = eval(“#{params[:controller]}_controller”.classify)
else
klass = self.class
end
klass.user_authorized_for?(current_user, params, binding)
end
end
end

Estoy manejando el plugin Role requirement, espero su ayuda.