Simplifica a utilização da autenticação em dois fatores.
É necessário implementar uma interface IQRCodeGenerator.
Recomendo a utilização da QRCoder
Instâncie a classe TwoFactorAuthService:
IQRCodeGenerator qrCodeGenerator = new QRCodeGenerator();
ITwoFactorAuthService service = new TwoFactorAuthService(qrCodeGenerator);
Ou a registre em seu IOC:
services.AddSingleton<IQRCodeGenerator, YourOwnQRCodeGenerator>();
services.AddSingleton<ITwoFactorAuthService, TwoFactorAuthService>();
Para simplificar testes de unidade, o serviço possui a interface ITwoFactorAuthService.
Existem três comportamentos possíveis no serviço, são eles:
- GenerateQrCode: Esse método gera um QRCode para inserir o chave no autenticador;
- ValidateCode: Responsável por válidar um código fornecido;
- GetNextCode: Retorna o próximo código disponível.
TwoFactorAuthIssuer twoFactorAuthIssuer = new TwoFactorAuthIssuer("<qualquer valor até 20 caracteres>");
TwoFactorAuthLabel twoFactorAuthLabel = new TwoFactorAuthLabel("<qualquer valor até 20 caracteres>");
TwoFactorAuthSecret twoFactorAuthSecret = new TwoFactorAuthSecret("<segredo em base 32 segundo RFC 3548>");
var qrCodeStream = await service.GenerateQrCodeAsync(twoFactorAuthIssuer, twoFactorAuthLabel, twoFactorAuthSecret, cancellationToken);
Se não quiser gerar seu próprio secret, você poderá usar o tipo HashidTwoFactorAuthSecret.
TwoFactorAuthSecret twoFactorAuthSecret = new HashidTwoFactorAuthSecret();
TwoFactorAuthCode code = new TwoFactorAuthCode("<Código de 6 dígitos>");
TwoFactorAuthSecret secret = new TwoFactorAuthSecret("<Mesmo segredo utilizado na geração do QRCode>");
TwoFactorVerificationRange range = new TwoFactorVerificationRange(<Valor de 0-5 indicando a janela de códigos verificado>)
try {
await service.ValidateQRCodeAsync(code, secret, range, cancellationToken);
}
catch (TwoFactorAuthCodeInvalidException ex) {
// Tratamento para código inválido
}
TwoFactorVerificationRange permite selecionar uma janela de tempo para verificação de códigos.
Imagine que o parâmetro 1 é fornecido. Durante a validação do código, aceitaremos como válido:
- se o valor anterior ao atual (-1) for o código fornecido;
- se o valor atual for o código fornecido;
- ou se posterior ao atual (+1) for o código fornecido.
Tendo em vista que os códigos são gerados com base no tempo, pode ocorrer uma pequena "confusão" entre cliente (App de autenticação) e servidor (Validador do código).
TwoFactorAuthSecret secret = new TwoFactorAuthSecret("<Mesmo segredo utilizado na geração do QRCode>");
TwoFactorAuthCode code = await service.GetNextCodeAsync(secret, cancellationToken);