Yauth
Yauth is a extremely simple authentication solution for prototypes, and provides a drop-in solution for http basic authentication. It uses a yaml file to store usernames and hashed password combined with the http basic authentication. The whole gem provides a better-than-nothing security, and it was designed with small prototypes in mind. It is entirely developed as a github.com/hassox/warden strategy, the same library on which the popular Devise is based.
Yauth resolves one well defined problem: protecting a web application that is going to be accessed by a few users. As adding new users requires manual intervention (only launching a command, see below), it’s a good choice for single-users web applications or prototypes. In this way you can password-protect your app easily and expose it to your clients on the web.
Installation
First, install the gem:
gem install yauth
Or if you are using Bundler:
echo "gem 'yauth'" >> Gemfile
bundle install
Add the first user (username ‘bar’ and password ‘foo’):
yauth add foo
Check the ‘config/users.yml’ into your version control system:
git add config/users.yml
git commit -m "Added user 'bar'."
Configuration
Yauth requires almost no configuration, 5 lines of code.
Sinatra
In your application.rb, simply put:
Yauth::Strategy.install!
use Warden::Manager do |manager|
manager.default_strategies :yauth_users
manager.failure_app = Yauth::FailureApp.new("Your Realm")
end
To require authentication inside an action, simply call:
get '/' do
request.env['warden'].authenticate! # execution stop and auth is required
"hello world\n"
end
Rails 3
In your config/application.rb file put:
Yauth::Strategy.install!
config.middleware.use Warden::Manager do |manager|
manager.default_strategies :yauth_users
manager.failure_app = Yauth::FailureApp.new("Your Realm")
end
To require authentication inside an action, add this method to app/controllers/application_controller.rb:
private
def authenticate
env['warden'].authenticate!
end
Then, you can use the authenticate
method as a before filter for every method that requires authentication:
before_filter :authenticate, :only => :your_method_here
Adding and removing users
If you want to add the user ‘foo’, with password ‘bar’, just launch:
yauth add foo
Then, if you want to change ‘foo’ password to ‘oof’, just launch:
yauht add foo oof
Finally, to remove ‘foo’ user:
yauth rm foo
Security Considerations
Users are stored in the ‘config/users.yml’ file, with the password stored using BCrypt (github.com/codahale/bcrypt-ruby). In this way it’s safe to add the ‘config/users.yml’ to the version control system.
You can see an example of the ‘config/users.yml’ file:
---
- user:
username: admin
password: !str:BCrypt::Password
str: $2a$10$UMR/fB5Jn5oRNe.OV9VicOLrg9BnPyN6Vc3S/noI5LWzfMKK2Zj0q
"@checksum": Lrg9BnPyN6Vc3S/noI5LWzfMKK2Zj0q
"@cost": 10
"@salt": $2a$10$UMR/fB5Jn5oRNe.OV9VicO
"@version": !str:BCrypt::Password 2a
Upgrading from version 0.1 to 0.2
YOU MUST RECREATE your users.yml file when migrating from 0.1 to 0.2, as I changed the encryption function to BCrypt. Unfortunately it’s pretty cheap to crack a password encrypted inside an hash, as stated in this article: codahale.com/how-to-safely-store-a-password. And one of the main goals of this project it’s to store passwords securely. Beware that it might be slower to compute, but it is much safer with BCrypt.
This has been done thanks to Gabriele Renzi, that has pointed me in the right direction.
TODO
Future versions will include:
-
drop-in api key solution, i.e. user might have a key for API prototypation;
-
hash function independence;
-
authentication scopes, as defined in warden.
Contributing to yauth
-
Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
-
Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
-
Fork the project
-
Start a feature/bugfix branch
-
Commit and push until you are happy with your contribution
-
Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright
Copyright © 2011 Matteo Collina. See LICENSE.txt for further details.