Autenticação de dois fatores sem esforço em Rails

Os aplicativos da web de hoje estão enfrentando todos os tipos de intrusões de segurança comumente derivadas de ataques de quebra de senha . O próprio usuário pode até mesmo escrever a senha em algum lugar acessível a partes não confiáveis, tornando mais fácil para ladrões de identidade acessar informações privadas ou, pior, assumir a conta do usuário.

Uma das maneiras mais eficazes de resolver essa situação é exigir segredos adicionais que os proprietários de contas reais possam obter de outros canais depois de entrarem com seu e-mail e senha normais. Esses segredos adicionais são conhecidos como senhas de uso único e são a base da autenticação de dois fatores .

A implementação de One-Time-Password não deve ser uma tarefa penosa, é por isso que estamos introduzindo a gem ActiveModel :: Otp .

ActiveModel :: Otp funciona em qualquer aplicação Rails e pode ser configurado em apenas alguns passos. Primeiro vamos adicionar um campo ao nosso modelo de usuário, para que cada usuário possa ter uma chave secreta otp.

rails g migration AddOtpSecretKeyToUsers otp_secret_key:string
=>
invoke active_record

create db
/migrate/20130707010931_add_otp_secret_key_to_users.rb

Em seguida, precisaremos executar para atualizar a tabela de usuários no banco de dados. A próxima etapa é atualizar o código do modelo. Precisamos usar has one time_password para dizer que será usado o TFA.rake db:migrate

class User < ActiveRecord::Base
has_one_time_password

end

A has_one_time_passwordfrase fornece ao modelo alguns métodos úteis para implementar nosso sistema TFA.
A chave secreta otp é salva automaticamente quando um objeto é criado, a chave secreta otp é gerada de acordo com RFC 4226 e HOTP RFC . Isso é compatível com os aplicativos Google Authenticator disponíveis para Android e iPhone, e agora em uso no GMail.

user = User.create(email: "hello@heapsource.com")
user
.otp_secret_key
=> "jt3gdd2qm6su5iqh
  • Obtendo o código atual (você também pode enviá-lo por SMS)
user.otp_code # => '186522'
sleep
30
user
.otp_code # => '850738'
  • Autenticar usando um código
user.authenticate_otp('186522') # => true
sleep
30 # let's wait 30 secs
user
.authenticate_otp('186522') # => false
  • Autenticar usando um código um pouco antigo
user.authenticate_otp('186522') # => true
sleep
30 # lets wait again
user
.authenticate_otp('186522', drift: 60) # => true

Compatível com Google Authenticator

A biblioteca funciona com o aplicativo Google Authenticator para iPhone e Android e também inclui a capacidade de gerar URIs de provisionamento para usar com o scanner de código QR integrado ao aplicativo.

# Use you user's emails for generate the provision_url
user
.provision_uri # => 'otpauth://totp/hello@heapsource.com?secret=2z6hxkdwi3uvrnpn'

# Use a custom fied for generate the provision_url
user
.provision_uri("hello") # => 'otpauth://totp/hello?secret=2z6hxkdwi3uvrnpn'

Isso pode então ser processado como um código QR que pode ser digitalizado e adicionado à lista de usuários de credenciais OTP.

Exemplo de trabalho

Digitalize o seguinte código de barras com o seu telefone, usando o Google Authenticator.

CÓDIGO QR

Agora execute o seguinte e compare a saída:

require "active_model_otp"
class User
extend
ActiveModel::Callbacks
include
ActiveModel::Validations
include
ActiveModel::OneTimePassword

define_model_callbacks
:create
attr_accessor
:otp_secret_key, :email

has_one_time_password

end
user
= User.new
user
.email = 'roberto@heapsource.com'
user
.otp_secret_key = "2z6hxkdwi3uvrnpn"
puts
"Current code #{user.otp_code}"

Você pode bifurcar o aplicativo Google Authentication para iPhone e Android e personalizá-lo.

Provavelmente iremos aprimorar a joia com bons geradores de rails e bibliotecas de cliente para iOS e Android. Siga este blog e para obter atualizações sobre esta joia e outras iniciativas de código aberto de nossa empresa.