Visão Geral
Atualmente a plataforma Latromi conta com Single Factor Authentication, ou seja, autenticação de apenas um fator (usuário + senha). No entanto, hoje em dia, as corporações estão cada vez mais preocupadas com a segurança da informação, seja por boas práticas ou para atender a normas regulatórias, como a ISO 27001.
Esta implementação tem como objetivo adicionar o recurso de MFA (Multi Factor Authentication) à plataforma Latromi.
Como vai funcionar?
Em resumo, após a validação de usuário + senha no processo de autenticação, o usuário será desafiado à informar um código de 6 dígitos que terá sido enviado ao seu e-mail. O usuário só poderá navegar no site após resolver este desafio.
Configurações de E-mail
As configurações de e-mail devem ser cadastradas através de uma rotina que deve ser adicionada ao módulo Latromi Essentials. Várias contas de e-mail poderão ser cadastradas.
Configurações do site
Nas Configurações do Site, teremos um novo campo que vai determinar o comportamento de uso padrão do MFA para os usuários:
- MFA habilitado por padrão:
Sim / Não
Teremos também um novo campo para selecionar a conta de e-mail que será utilizada para envio de códigos de MFA:
- E-mail para envio de códigos MFA:
Caixa de seleção com contas de e-mail cadastradas
Cadastro de Usuários
No cadastro de usuários, teremos um novo campo que vai determinar o comportamento de uso do MFA:
- MFA habilitado:
Sim / Não / Padrão do sistema
O valor “Padrão do sistema” deve ser o valor padrão. Quando estiver selecionado deve respeitar o que está definido nas Configurações do Site.
Sessão do Usuário
Quando um usuário habilitado para usar MFA realizar a autenticação na plataforma, a coluna status
da sessão de trabalho deve ficar com o novo valor 4 (Awaiting Next Factor)
.
Nesta situação, um código de autenticação de 6 dígitos deve ser gerado na coluna token
da tabela core.mfatokens
, associado à sessão e enviado por e-mail para o usuário. Inicialmente, a duração do token deve ser de 5 minutos.
Context Token
A coluna contexttoken
da tabela core.mfatokens
deve receber um valor UUID
único. Este valor deve ser retornado para o usuário de forma transparente (através de cookie ou armazenado em memória). É através do Context Token que o token de 6 dígitos será encontrado para a validação.´
A implementação do Context Token evita o “desencontro” entre tokens gerados e tentativas de autenticação de um mesmo usuário em dispositivos diferentes.
Processo de Autenticação
O processo de autenticação deve receber uma nova etapa (habilitada conforme configuração do MFA) que desafia o usuário a informar um código recebido por e-mail.
Quando o MFA estiver habilitado, o fluxo será este:
-
Credenciais de acesso são validadas pela rotina de autenticação.
-
A sessão de trabalho é gerada com status
4
. -
Uma nova linha é gerada na tabela
core.mfatokens
. -
O código de 6 dígitos deve ser enviado ao usuário por e-mail.
-
O Context Token é retornado para o usuário (no navegador ou Latromi Client).
-
O usuário é redirecionado para uma nova tela para informar o código de 6 dígitos.
-
O usuário informa o código de 6 dígitos e envia para o servidor junto com o Context Token.
-
No servidor, o registro da tabela
core.mfatokens
deve ser encontrado através do Context Token. Quando encontrado, o código de 6 dígitos informado pelo usuário deve ser comparado com otoken
gravado no registro:- Se o token estiver expirado (
creationtime
+duration
), retornar erro e repetir o processo. - Se os tokens forem diferentes, retornar erro e repetir o processo.
- Se os tokens forem iguais, trocar o
status
da sessão de trabalho para1. Active
e permitir a entrada do usuário.
- Se o token estiver expirado (
Reenvio do Código
Na tela onde o usuário vai informar o código de 6 dígitos, deve ser possível “reenviar o código”. Quando a rotina de reenvio de código for acionada, uma nova linha na tabela core.mfatokens
deve ser gerada e um novo contexttoken
deve ser retornado ao usuário.
Estrutura de banco de dados
Abaixo os scripts para modificação da estrutura de banco de dados para desenvolvimento desta rotina.
schema wecdb
SET SEARCH_PATH = wecdb;
-- Configurações do site
ALTER TABLE configuracao ADD mfabydefault BOOLEAN NOT NULL DEFAULT FALSE;
COMMENT ON COLUMN configuracao.mfabydefault IS 'Usar MFA (Multi factor autentication) por padrão';
ALTER TABLE usuario ADD mfaenabled SMALLINT NOT NULL DEFAULT 2;
COMMENT ON COLUMN usuario.mfaenabled IS 'Indica se o usuário deve usar autenticação MFA (Multi factor autentication):
0. Não
1. Sim
2. Padrão do sistema';
-- Sessão de trabalho
COMMENT ON COLUMN sessaotrabalho.status IS 'Situação da Sessão de Trabalho
0. Awaiting Activation.
1. Active.
2. Closing Required (um pedido de fechamento da sessão foi realizado).
3. Closed
4. Awaiting Next Factor';
schema core
SET SEARCH_PATH = core;
-- Tabela de tokens gerados para autenticação de multi fatores
CREATE TABLE mfatokens (
id SERIAL NOT NULL,
sessionid BIGINT NOT NULL,
token VARCHAR(6) NOT NULL,
contexttoken UUID NOT NULL,
creationtime TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
duration INTERVAL,
CONSTRAINT pk_mfatokens_id PRIMARY KEY (id),
CONSTRAINT uk_mfatokens_contextsession UNIQUE (contexttoken),
CONSTRAINT fk_mfatokens_sesionid FOREIGN KEY (sessionid)
REFERENCES wecdb.sessaotrabalho(id) ON DELETE CASCADE ON UPDATE CASCADE
);
COMMENT ON TABLE mfatokens IS 'Tabela que armazena os tokens de autenticação de 2 fatores dos usuário.';
COMMENT ON COLUMN mfatokens.id IS 'Identificador do token';
COMMENT ON COLUMN mfatokens.sessionid IS 'Identificador da sessão de trabalho';
COMMENT ON COLUMN mfatokens.token IS 'Token de 6 digitos';
COMMENT ON COLUMN mfatokens.contexttoken IS 'O token de contexto é gerado após as credenciais do usuário terem sido validadas. Este token é retornado para o usuário de forma transparente, e é usado para encontrar o token de 6 digítos correspondente a tentativa de login. Esta abordagem é usada para evitar problemas de concorrência quando o mesmo usuário estiver fazendo a autenticação em dispositivos diferentes ao mesmo tempo.';
COMMENT ON COLUMN mfatokens.creationtime IS 'Data e hora em que o token foi gerado';
COMMENT ON COLUMN mfatokens.duration IS 'Duração do token';
CREATE TABLE emailsettings
(
id SERIAL NOT NULL,
name TEXT NOT NULL,
creationtime TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
modificationtime TIMESTAMPTZ,
outgoingserver TEXT,
outgoingport INT,
outgoingusername TEXT,
outgoingpassword TEXT,
outgoingsslmode TEXT NOT NULL DEFAULT 'None',
CONSTRAINT pk_emailsettings_id PRIMARY KEY (id),
CONSTRAINT ck_emailsettings_outgoingsslmode CHECK (UPPER(outgoingsslmode) IN ('NONE', 'SSL/TSL', 'STARTTLS', 'STARTTLS?'))
);
COMMENT ON TABLE emailsettings IS 'Conjunto de configurações de e-mail';
COMMENT ON COLUMN emailsettings.id IS 'Identificador do conjunto de configurações de e-mail';
COMMENT ON COLUMN emailsettings.name IS 'Nome do conjunto de configurações de e-mail';
COMMENT ON COLUMN emailsettings.creationtime IS 'Data e hora de criação do registro';
COMMENT ON COLUMN emailsettings.modificationtime IS 'Data e hora da última modificação do registor';
COMMENT ON COLUMN emailsettings.outgoingserver IS 'Endereço do servidor de saída de e-mails';
COMMENT ON COLUMN emailsettings.outgoingport IS 'Porta do servidor de saída de e-mails';
COMMENT ON COLUMN emailsettings.outgoingusername IS 'Usuário de autenticação no servidor de saída de e-mails';
COMMENT ON COLUMN emailsettings.outgoingpassword IS 'Senha do usuário de autenticação no servidor de saída de e-mails';
COMMENT ON COLUMN emailsettings.outgoingsslmode IS 'Modo SSL de comunicação com o servidor de saída de e-mails: NONE, SSL/TSL, StartTLS, StartTLS? (When Available)';
Oportunidades de Melhorias
- Configuração da duração do token.
- Configuração de número limite de tentativas de validação do código.