跳到内容

TOTP 身份验证

编辑此页

TOTP 身份验证使用 TOTP 算法生成身份验证码。与 Google Authenticator 双因素提供程序相比,TOTP 双因素提供程序提供更多配置选项,但这表示您的配置不一定与 Google Authenticator 应用兼容。

几个参数可以自定义

  • 数字位数 (默认 = 6)
  • 摘要算法 (默认 = sha1)
  • 周期 (默认 = 30 秒)
  • 可以添加自定义参数

提示

使用默认值配置与 Google Authenticator 兼容的 TOTP (6 位数字,sha1 算法,30 秒周期)。

身份验证工作原理

用户必须首先将其帐户链接到 TOTP。这通过生成一个共享密钥代码来完成,该代码存储在用户实体中。用户可以通过手动输入代码以及配置 TOTP 算法的其他属性,或者通过扫描自动传输信息的二维码,将代码添加到 TOTP 应用。

成功身份验证后,bundle 会检查用户实体中是否存储了密钥。如果是这样,它将请求身份验证码。用户必须输入 TOTP 应用中当前显示的代码才能获得访问权限。

安装

要使用此功能,您必须安装 scheb/2fa-totp

1
composer require scheb/2fa-totp

基本配置

要启用此身份验证方法,请将其添加到您的配置中

1
2
3
scheb_two_factor:
    totp:
        enabled: true

您的用户实体必须实现 Scheb\TwoFactorBundle\Model\Totp\TwoFactorInterface。要为用户激活此方法,请生成密钥并定义 TOTP 配置。TOTP 允许您配置临时代码的位数、算法和周期。

注意

请注意,自定义配置将不再与 Google Authenticator 应用的默认设置兼容。您将必须使用另一个应用程序 (例如 Android 上的 FreeOTP)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php

namespace Acme\Demo\Entity;

use Doctrine\ORM\Mapping as ORM;
use Scheb\TwoFactorBundle\Model\Totp\TotpConfiguration;
use Scheb\TwoFactorBundle\Model\Totp\TotpConfigurationInterface;
use Scheb\TwoFactorBundle\Model\Totp\TwoFactorInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class User implements UserInterface, TwoFactorInterface
{
    /**
     * @ORM\Column(type="string", nullable=true)
     */
    private ?string $totpSecret;

    // [...]

    public function isTotpAuthenticationEnabled(): bool
    {
        return $this->totpSecret ? true : false;
    }

    public function getTotpAuthenticationUsername(): string
    {
        return $this->username;
    }

    public function getTotpAuthenticationConfiguration(): ?TotpConfigurationInterface
    {
        // You could persist the other configuration options in the user entity to make it individual per user.
        return new TotpConfiguration($this->totpSecret, TotpConfiguration::ALGORITHM_SHA1, 20, 8);
    }
}

配置选项

1
2
3
4
5
6
7
8
9
scheb_two_factor:
    totp:
        enabled: true                  # If TOTP authentication should be enabled, default false
        server_name: Server Name       # Server name used in QR code
        issuer: Issuer Name            # Issuer name used in QR code
        leeway: 0                      # Acceptable time drift in seconds, must be less or equal than the TOTP period
        parameters:                    # Additional parameters added in the QR code
            image: 'https://my-service/img/logo.png'
        template: security/2fa_form.html.twig   # Template used to render the authentication form

附加参数

您可以设置将添加到 provisioning URI 的附加参数,该 URI 包含在二维码中。参数对于所有用户都是通用的。自定义参数可能不受所有应用程序的支持,但对于自定义二维码非常有趣。在下面的示例中,我们添加了一个 image 参数,其中包含服务徽标的 URL。某些应用程序 (例如 FreeOTP) 支持此参数,并将二维码与该徽标关联。

1
2
3
4
scheb_two_factor:
    totp:
        parameters:
            image: 'https://my-service/img/logo.png'

自定义身份验证表单模板

bundle 使用 Resources/views/Authentication/form.html.twig 来渲染身份验证表单。如果您想使用不同的模板,您可以简单地在配置中注册它

1
2
3
scheb_two_factor:
    totp:
        template: security/2fa_form.html.twig

自定义表单渲染

在某些情况下,仅更改模板是不够的。例如,您在多个防火墙上使用双因素身份验证,并且需要为每个防火墙以不同的方式渲染表单。在这种情况下,您可以实现一个表单渲染器来完全自定义渲染逻辑。

创建一个类,实现 Scheb\TwoFactorBundle\Security\TwoFactor\Provider\TwoFactorFormRendererInterface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

namespace Acme\Demo\FormRenderer;

use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\TwoFactorFormRendererInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class MyFormRenderer implements TwoFactorFormRendererInterface
{
    // [...]

    public function renderForm(Request $request, array $templateVars): Response
    {
        // Customize form rendering
    }
}

然后将其注册为服务并更新您的配置

1
2
3
4
# config/packages/scheb_2fa.yaml
scheb_two_factor:
    totp:
        form_renderer: acme.custom_form_renderer_service

生成密钥

服务 scheb_two_factor.security.totp_authenticator 提供了一种为 TOTP 身份验证生成新密钥的方法。Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Totp\TotpAuthenticatorInterface 的自动装配也是可能的。

1
$secret = $container->get("scheb_two_factor.security.totp_authenticator")->generateSecret();

二维码

要生成可以被身份验证器应用程序扫描的二维码,请从 TOTP 服务检索二维码的内容

1
$qrCodeContent = $container->get("scheb_two_factor.security.totp_authenticator")->getQRContent($user);

使用您选择的二维码渲染库来渲染二维码图像。

关于如何使用 endroid/qr-code 版本 4 渲染二维码的示例可以在 演示应用程序中找到。

注意

安全提示:将二维码内容保留在您的应用程序中。自行渲染图像。不要将内容传递给外部服务,因为这会将密钥泄露给该服务。

这项工作,包括代码示例,均根据 Creative Commons BY-SA 3.0 许可获得许可。
目录
    版本