Code Monkey home page Code Monkey logo

restful-authentication's Introduction

This widely-used plugin provides a foundation for securely managing user authentication:

  • Login / logout
  • Secure password handling
  • Account activation by validating email
  • Account approval / disabling by admin
  • Rudimentary hooks for authorization and access control.

Several features were updated in May, 2008.

IMPORTANT: if you upgrade your site, existing user account passwords will stop working unless you use --old-passwords


Issue Tracker

Please submit any bugs or annoyances on the lighthouse tracker at

For anything simple enough, please github message both maintainers: Rick Olson ("technoweenie":http://github.com/technoweenie) and Flip Kromer ("mrflip":http://github.com/mrflip).


Documentation

This page has notes on

  • "Installation":#INSTALL
  • "New Features":#AWESOME
  • "After installing":#POST-INSTALL

See the "wiki":http://github.com/technoweenie/restful-authentication/wikis/home (or the notes/ directory) if you want to learn more about:

  • "Extensions, Addons and Alternatives":addons such as HAML templates
  • "Security Design Patterns":security-patterns with "snazzy diagram":http://github.com/technoweenie/restful-authentication/tree/master/notes/SecurityFramework.png
  • Authentication -- Lets a visitor identify herself (and lay claim to her corresponding Roles and measure of Trust)
  • "Trust Metrics":Trustification -- Confidence we can rely on the outcomes of this visitor's actions.
  • Authorization and Policy -- Based on trust and identity, what actions may this visitor perform?
  • Access Control -- How the Authorization policy is actually enforced in your code (A: hopefully without turning it into a spaghetti of if thens)
  • Rails Plugins for Authentication, Trust, Authorization and Access Control
  • Tradeoffs -- for the paranoid or the curious, a rundown of tradeoffs made in the code
  • CHANGELOG -- Summary of changes to internals
  • TODO -- Ideas for how you can help

These best version of the release notes are in the notes/ directory in the "source code":http://github.com/technoweenie/restful-authentication/tree/master -- look there for the latest version. The wiki versions are taken (manually) from there.


Exciting new features

Stories

There are now "Cucumber":http://wiki.github.com/aslakhellesoy/cucumber/home features that allow expressive, enjoyable tests for the authentication code. The flexible code for resource testing in stories was extended from "Ben Mabey's.":http://www.benmabey.com/2008/02/04/rspec-plain-text-stories-webrat-chunky-bacon/

Modularize to match security design patterns:

  • Authentication (currently: password, browser cookie token, HTTP basic)
  • Trust metric (email validation)
  • Authorization (stateful roles)
  • Leave a flexible framework that will play nicely with other access control / policy definition / trust metric plugins

Other

  • Added a few helper methods for linking to user pages
  • Uniform handling of logout, remember_token
  • Stricter email, login field validation
  • Minor security fixes -- see CHANGELOG

Non-backwards compatible Changes

Here are a few changes in the May 2008 release that increase "Defense in Depth" but may require changes to existing accounts

  • If you have an existing site, none of these changes are compelling enough to warrant migrating your userbase.
  • If you are generating for a new site, all of these changes are low-impact. You should apply them.

Passwords

The new password encryption (using a site key salt and stretching) will break existing user accounts' passwords. We recommend you use the --old-passwords option or write a migration tool and submit it as a patch. See the [[Tradeoffs]] note for more information.

Validations

By default, email and usernames are validated against a somewhat strict pattern; your users' values may be now illegal. Adjust to suit.


Installation

This is a basic restful authentication generator for rails, taken from acts as authenticated. Currently it requires Rails 1.2.6 or above.

IMPORTANT FOR RAILS > 2.1 USERS To avoid a @NameError@ exception ("lighthouse tracker ticket":http://rails_security.lighthouseapp.com/projects/15332-restful_authentication/tickets/2-not-a-valid-constant-name-errors#ticket-2-2), check out the code to have an underscore and not dash in its name:

  • either use git clone git://github.com/technoweenie/restful-authentication.git restful_authentication
  • or rename the plugin's directory to be restful_authentication after fetching it.

To use the generator:

./script/generate authenticated user sessions
--include-activation
--stateful
--rspec
--skip-migration
--skip-routes
--old-passwords

  • The first parameter specifies the model that gets created in signup (typically a user or account model). A model with migration is created, as well as a basic controller with the create method. You probably want to say "User" here.

  • The second parameter specifies the session controller name. This is the controller that handles the actual login/logout function on the site. (probably: "Session").

  • --include-activation: Generates the code for a ActionMailer and its respective Activation Code through email.

  • --stateful: Builds in support for acts_as_state_machine and generates activation code. (@--stateful@ implies @--include-activation@). Based on the idea at [[http://www.vaporbase.com/postings/stateful_authentication]]. Passing @--skip-migration@ will skip the user migration, and @--skip-routes@ will skip resource generation -- both useful if you've already run this generator. (Needs the "acts_as_state_machine plugin":http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/, but new installs should probably run with @--aasm@ instead.)

  • --aasm: Works the same as stateful but uses the "updated aasm gem":http://github.com/rubyist/aasm/tree/master

  • --rspec: Generate RSpec tests and Stories in place of standard rails tests. This requires the "RSpec and Rspec-on-rails plugins":http://rspec.info/ (make sure you "./script/generate rspec" after installing RSpec.) The rspec and story suite are much more thorough than the rails tests, and changes are unlikely to be backported.

  • --old-passwords: Use the older password scheme (see [[#COMPATIBILITY]], above)

  • --skip-migration: Don't generate a migration file for this model

  • --skip-routes: Don't generate a resource line in @config/routes.rb@


After installing

The below assumes a Model named 'User' and a Controller named 'Session'; please alter to suit. There are additional security minutae in @notes/README-Tradeoffs@ -- only the paranoid or the curious need bother, though.

  • Add these familiar login URLs to your @config/routes.rb@ if you like:

    
      map.signup  '/signup', :controller => 'users',   :action => 'new'
      map.login  '/login',  :controller => 'session', :action => 'new'
      map.logout '/logout', :controller => 'session', :action => 'destroy'
      
  • With @--include-activation@, also add to your @config/routes.rb@:

    
      map.activate '/activate/:activation_code', :controller => 'users', :action => 'activate', :activation_code => nil
      

    and add an observer to @config/environment.rb@:

    
      config.active_record.observers = :user_observer
      

    Pay attention, may be this is not an issue for everybody, but if you should have problems, that the sent activation_code does match with that in the database stored, reload your user object before sending its data through email something like:

    
      class UserObserver < ActiveRecord::Observer
        def after_create(user)
          user.reload
          UserMailer.deliver_signup_notification(user)
        end
        def after_save(user)
          user.reload
          UserMailer.deliver_activation(user) if user.recently_activated?
        end
      end
      
  • With @--stateful@, add an observer to config/environment.rb:

    
      config.active_record.observers = :user_observer
      

    and modify the users resource line to read

    map.resources :users, :member => { :suspend => :put, :unsuspend => :put, :purge => :delete }

  • If you use a public repository for your code (such as github, rubyforge, gitorious, etc.) make sure to NOT post your site_keys.rb (add a line like '/config/initializers/site_keys.rb' to your .gitignore or do the svn ignore dance), but make sure you DO keep it backed up somewhere safe.

restful-authentication's People

Contributors

andrew avatar barrym avatar bjhess avatar bryan-ash avatar bscofield avatar codafoo avatar ggoodale avatar gramos avatar jakimowicz avatar jicksta avatar johnmunsch avatar kamal avatar lancecarlson avatar lightcap avatar lsimoneau avatar mhennemeyer avatar mrduncan avatar nbibler avatar oboxodo avatar redmar avatar romanbsd avatar technoweenie avatar zaach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

restful-authentication's Issues

Default redirect for 'SessionsController#create' template is hard coded

In the SessionsController#create and SessionsController#destroy actions, the path for redirect_back_or_default is hard coded to '/'. Could this be changed to root_path for users that have the rails app running under a sub-url? Since this can be changed pretty easy by the user, might not need a "fix", but would be a lot easier.

Not on rubygems.org

I'm prep'ing an app for upgrading to rails 3. I want to switch plugins to gems where possible so I can manage them with bundler and more easily upgrade everything to the latest versions.

I found restful-authentication has a gemspec with:
s.version = "1.1.1"

But I had no luck installing that version, or any, via the rubygems.org gem source.

There may be a good argument for using restful-authentication just as a plugin, but in general, gems with bundler does make managing versions easier and I'd have saved 10 mins if "gem install restful-authentication -v 1.3.0" had just worked.

I'd really appreciate it if you can publish restful-authentication to rubygems, and I'm sure it would help many others too.

Cheers,
Chris

uninitialized constant OpenSSL::Digest::SHA1 in rails 3 and ubuntu

Hi All,

I am trying to integrate restful_authentication plugings into my rails 3 application. I integrated this in windows, but while trying to integrate it to ubuntu I am facing an error "uninitialized constant OpenSSL::Digest::SHA1"

I googled for the solution but still unsuccessful. I am unable to load the file, "require Digest/SHA1"

Now, i tried to run console screen. and tried to check the Digest file by putting print statement, this gives false, while in the irb it returns true.

If anyone has come across such problem

Cucumber issues

I just set up restful_auth with the cucumber tests on rails 2.3.5 and Ruby 1.9 and found that the user step
Then /^she should +see an? (\w+) message '([\w !']+)'$/ do |notice, message|
response.should have_flash(notice, %r{#{message}})
end

should be

Then /^she should +see an? (\w+) message '([\w !\']+)'$/ do |notice, message|
  response.should have_flash(notice, :content => %r{#{message}})
end

for things to work. Don't know if something changed recently that would have this work before but not now, but it all goes back to the have_flash which depends on have_tag, which in turn (so far as I can tell) looks for content if you send in content through a hash. Perhaps it used to look for any second argument as though it were content, but if so it is doing so wonkily now.

Password validation on all attribute updates

Whenever I try to update an attribute of the user, the password validations kick in and throws an error because no password is sent to the update.

I don't want to turn off validations and use save(false) everywhere but registration. And I want to use update_attributes(params[:user]) since it's very convenient.

Is there a way to only have the password validations kick in when the password is supposed to be validated (ie on registration and password change)?

Thanks!

Possible that person is logged in as wrong user with cookie token

I built a site using 1.1.1 of the plugin. We've had 2 instances where people have reported being logged in as the wrong user. I just found out in at least one of those cases it was after viewing their profile from a bookmark so presumably using authentication by cookie. This fault has been impossible to reproduce. Is it possible users ended up with the same remember_token? The odds of that happening even once seem ridiculously small. Have you heard of anything like this happening?
I've added a unique constraint to that column as a precaution anyway.
Many thanks
David North

missed issue in documentation

Hi,
you have missed issue in installation instructions, that users should add line "include AuthenticatedSystem" to the application controller. Could you correct it plz?

removed installation instructions as submodule

not sure why it was removed, but now it just says
either use git clone git://github.com/technoweenie/restful-authentication.git restful_authentication
or rename the plugin’s directory to be restful_authentication after fetching it.

previously had instructions to add as submodule if using git.
git submodule add git://github.com/technoweenie/restful-authentication.git vendor/plugins/restful_authentication

database session store

Hi, I am pretty new to Rails although I have been learning it for the past 2 months. I am having trouble using the mysql database active record session store with this plug-in. I keep getting the following error when I try to log-in: ActionController::InvalidAuthenticityToken in SessionsController#create . And each time I go to the login page or any other page for that matter, it creates a new session entry in the sessions table. How can i get the database session store to work properly? I am using rails 2.3.2.

Any help would be useful!

SecurityError

In my Rails application, in production mode, when a user signs up I got the following error:

SecurityError (calling insecure method: make_activation_code): app/controllers/utenti_controller.rb:76:in `create' public/dispatch.fcgi:24

Configuration:

  • ruby 1.8.6 (2009-06-08 patchlevel 369)
  • rails 2.3.5

I've not found any information on the Web, any helpful hint?

Mevio

Master branch broken create user method

NoMethodError in UsersController#create

undefined method `name' for #User:0x23b5400

This is caused by validations in user.rb for :name since the name field is not part of the initial migration.

validates_format_of :name, :with => Authentication.name_regex, :message => Authentication.bad_name_message, :allow_nil => true
validates_length_of :name, :maximum => 100

Removing these lines fixes the issue.

remember_me will never work?

Am I wrong or will remember_me never work? In my opinion two lines are missing in 'by_cookie_token.rb' file (see patch):

Index: restful_authentication/lib/authentication/by_cookie_token.rb

--- restful_authentication/lib/authentication/by_cookie_token.rb
+++ restful_authentication/lib/authentication/by_cookie_token.rb
@@ -42,8 +42,10 @@
# refresh token (keeping same expires_at) if it exists
def refresh_token
if remember_token?

  •      self.remember_token = self.class.make_token 
    
  •      save(false)  
    
  •      self.remember_token = self.class.make_token
    
  •      save(false)
    
  •    else
    
  •      remember_me
     end
    
    end

consuming plugin's authentication data in other languages (java)

Hi

Our ROR portal, using this plugin, has a huge databse of users, for each user the authentication data (username, password, salt) was saved in database (Varchar types, MySql).

We need now to authenticate this huge user database in java application. Now, I could found ANY INFO on how this plugins generates salted hashes.

For using the authentication data in java, we need to assume something like this:

Pluging takes raw password, appends SALT, then make a digest, and then this data is saved as BASE-64 encoded string.

Can you please give the exact formula on how the encrypted password are generated ?

Thanks in advance, m.

Rake deprecation warning for Rails 2.3.10

DEPRECATION WARNING: Rake tasks in vendor/plugins/restful_authentication/tasks are deprecated.

Use lib/tasks instead. (called from /home/benoror/app/vendor/rails/railties/lib/tasks/rails.rb:10)

Forceful Migrations

The migration generator automatically creates a forceful create_table, this is so dangerous I don't even know where to start. Why is it even there, it would be great to be given an error or a heads up that it's about to destroy an existing table. Not amused.

note_failed_signin unescaped string

Line 40 of the note_failed_signin in generators / authenticated / templates / controller.rb

flash[:error] = "Couldn't log you in as '#{params[:login]}'"

Is unescaped and could lead to a potential XSS attack where an attacker could steal the users credentials. It should be:

flash[:error] = "Couldn't log you in as '#{CGI.escapeHTML(params[:login])}'"

Incompatible with Rails 3 bundler

When running bundle install with Rails edge and the current restful_authentication from gemcutter, it fails with:

No compatible versions could be found for required dependencies:
    Conflict on: "rails":
    * rails (3.0.0.beta1) activated by rails (>= 0, runtime)
    * rails (~> 2.3.4, runtime) required by restful_authentication (>= 0, runtime)
    All possible versions of origin requirements conflict.

Validation with Authentication.email_regex fails on some RFC5322-valid addresses

Issue:
The current Authentication.email_regex code does not check for certain characters that are approved by RFC5322 part 3.2.3. Specifically, the code does not check for the following symbols: !, #, $, &, ', *, /, =, ?, ^, `, {, |, }, or ~.
http://tools.ietf.org/html/rfc5322#section-3.2.3

Example:
An RFC5322-valid email address of Tom.O'[email protected] will fail the current email_regex test.

Solution:
Expand the Authentication.email_regex code to it better supports the RFC5322 specification.

Personal Thoughts:
The current Authentication.email_regex code works for the vast majority of email addresses.
In a nutshell, the code looks for valid "words" and a few specific symbols: ., %, +, -
Adding the missing symbols is one option: email_name_regex = '[\w!#$%&.'+-/=?^{|}~]+'.freeze I think that adding the missing symbols and replacing the current "word" check with specific characters is a better option: email_name_regex = '[a-zA-Z0-9!#$%&.\'_+-\/=?^_{|}~]+'.freeze
The code would be more specific about complying with RFC5322 part 3.2.3, while also setting the stage for full RFC5322 compliance.
(There are a few more rules that are required for full compliance, items like an email address cannot start with a period (.), and an email address cannot contain two consecutive periods (..))
The use of escape slashes in my proposed solution was based on this info from Ruby Doc: http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html#UL
Specifically:

  • All characters except ., |, (, ), [, , ^, {, +, $, *, and ? match themselves. To match one of these characters, precede it with a backslash.
  • The characters |, (, ), [, ^, $, *, and ?, which have special meanings elsewhere in patterns, lose their special significance between brackets.

recently_activated missing question mark (?) in generator

line 8 in restful_authentication\generators\authenticated\templates\observer.rb misses a question mark (?) after recently_activated (should be recently_activated?)
results in an error
NoMethodError (undefined method recently_activated' for #<User:0xxxxxxxxx>): app/models/user_observer.rb:8:inafter_save'

logout does not invalidate sessions when using ActiveRecord::SessionStore

The SessionsController#destroy action uses logout_killing_session! to log the user out. This effectively does 2 things:

  1. set the session's user_id to nil
  2. reset the session, which generates a new session id

The problem is that the changes made in step (1) are never persisted to the database. This allows anyone with access to the previous session id to access restricted pages without supplying any credentials.

I am not sure of the proper patch here, as Rails's middleware-based session handling loads and persists the session at a different layer. So it's awkward to "flush" the session to the database from inside the request cycle.

My workaround was a bit of a hack -- I just delete the session since I don't care about keeping it around:

ActiveRecord::SessionStore::Session.delete_all :session_id => request.session_options[:id]

Here is a blueprint of a test to replicate the behavior:

test "invalidates sessions after user has logged out" do
  user = Factory(:user)
  get login_url
  post_via_redirect create_session_url, :email => user.email, :password => user.password
  session_id_before_logout = cookies[SESSION_ID_COOKIE_KEY]
  get_via_redirect logout_url

  open_session do |attacker_session|
    attacker_session.cookies[SESSION_ID_COOKIE_KEY] = session_id_before_logout
    attacker_session.get some_url_in_your_app
    attacker_session.assert_redirected_to login_url
  end
end

NoMethodError when session kept in cookie is recovered

My environment:
ruby 1.8.7 + Rails 2.3.8

I met the following error when a session kept in cookie is recovered.

F, [2010-08-03T19:40:02.937000 #2624] FATAL -- :
NoMethodError (undefined method remember_token?' for true:TrueClass): lib/authenticated_system.rb:130:inlogin_from_cookie'
lib/authenticated_system.rb:12:in current_user' lib/authenticated_system.rb:6:inlogged_in?'
lib/authenticated_system.rb:35:in authorized?' lib/authenticated_system.rb:53:inlogin_required'

The error occurs because "true" is set to "user" variable in the following block in lib/authenticated_system.rb.

def login_from_cookie
  user = !cookies[:auth_token].blank? and User.find_by_remember_token(cookies[:auth_token])
  if user && user.remember_token?

The error disappeared after I replaced 'and' with '&&' as follows.

  user = !cookies[:auth_token].blank? && User.find_by_remember_token(cookies[:auth_token])

This may depend on ruby version or something.

Thanks,

ebi

password validation in model should override that set in plugin

I am using restful-authentication in a Rails app as a plug-in. I notice that the password validations are set within the plug-in's ByPassword module. However, if I modify these I believe my modifications could be lost if I update the plug-in or choose to use a different validation plug-in at a latter date.

I have tried entering my own password validation statement within my user model, but these seem to be over-ridden by those in the plug-in. For example: validates_length_of :password

Would it not be better if the plug-in provided default values, but these could be over-ridden by those set within the model. Surely application specific settings such as password validation rules, should be set in the model code and not the plug-in. The plug-in should provide the functionality but not the setting.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.