Intranet application with username/password authentication for LAN users. Remote users are required to use TFA.
- Authlogic handles authentication, there are no changes to Authlogic, TFA is completely separate and invoked after Authlogic authorization.
- Google Authenticator QR code secret entry without generating images (RQRCode) or sending secrets to the charting services.
- TFA confirmation will expire with the session but can expire before the session if required.
- TFA confirmation code brute force protection applies to the user, not just the session. Lockout after 5 failures, requires manual reset.
Correctable in a production application
- Production implementations must use SSL otherwise this implementation, and Authlogic itself, is vulnerable to session hijacking. See below for configuration options.
- TFA secret and TFA failure count reset is not implemented
- Users can view other user secrets, they should be scoped to the current user, i.e. a 'My Account' page.
- TFA Google Authenticator secret setup requires viewing the user record, the demo has all IP addresses including the localhost address restricted by default. This can be changed. See configuration options below.
git clone http://github.com/robertwahler/two_factor_authentication_example cd two_factor_authentication_example bundle install bundle exec rake db:migrate bundle exec rake db:seed bundle exec rails server
login creditials for the admin user
login: admin password: admin Google Authenticator time based two_factor_secret (spaces are optional): v6na sf4k fe45 qxbq
run the app
run the RSpec test suite
bundle exec rake db:test:prepare bundle exec rspec
for development, start-up the Spork process via Guard
bundle exec guard
Change TFA brute force failure count in app/models/user.rb
def two_factor_failure_count_exceeded? self.two_factor_failure_count >= 5 end
Change length of time the TFA confirmation is valid in app/models/user.rb
def two_factor_confirmed_at_valid_for 12.hours end
Change the sliding window width from the default of one 30 second window in app/controllers/user_sessions_controller.rb
# Use a sliding time window to validate tokens. System clock inaccuracy can # be tolerated at the expense a small decrease in security. A value of 0 # will disable the sliding window # # A value of 2 will check tokens in two windows before and after the current # 30 second window. ie. +/- 60 seconds surrounding the current window. # # @return [Integer] width of the window in 30 second increments def sliding_window_width 1 end
Change ApplicationController to allow all logins to bypass TFA
def two_factor_excluded_ip_addresses [IPAddress.parse("0.0.0.0/0")] end
Change ApplicationController to allow a localhost subnet to access without TFA
def two_factor_excluded_ip_addresses [IPAddress.parse("127.0.0.1/24")] end
Change ApplicationController to allow LAN subnet to access without TFA
def two_factor_excluded_ip_addresses [IPAddress.parse("10.0.0.1/24")] end
Change ApplicationController to allow both localhost and LAN subnet to access without TFA
def two_factor_excluded_ip_addresses [IPAddress.parse("127.0.0.1/24"), IPAddress.parse("10.0.0.1/24")] end
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = true
add these options to the session_store
:httponly => true, :secure => Rails.env.production?
- Authlogic for authentication http://github.com/binarylogic/authlogic
- ROTP for one time passwords http://github.com/mdp/rotp
- RQRCode for QR codes http://github.com/whomwah/rqrcode
- IPAddress for IP address range matching http://github.com/bluemonk/ipaddress
- UUIDTools for confirmation token timestamps http://github.com/sporkmonger/uuidtools
- Rspec for unit testing http://github.com/rspec/rspec
rails -v Rails 3.2.1
generate basic rails application
rails new two_factor_authentication_example --skip-bundle -T
gem "authlogic", "~> 3.1.0" gem "rotp", "~> 1.3.2" gem "rqrcode", "~> 0.4.2" gem "ipaddress", "~> 0.8.0" gem 'uuidtools', "~> 2.1.2" group :test, :development do gem "ruby-debug" gem "rspec-rails", "~> 2.8" gem "factory_girl_rails", "~> 1.6" gem "capybara", "~> 1.1" gem "database_cleaner", "~> 0.7.1" gem "timecop", "= 0.3.5" end
basic user scaffold and manual authlogic configuration
rails generate scaffold user email:string first_name:string last_name:string login:string --fixture-replacement
add admin user seed
rails new .
Copyright (c) 2012-2013 GearheadForHire, LLC. See LICENSE for details.