沙尘暴/Neo双因素认证

安装: 10,282

依赖: 0

建议者: 0

安全: 0

星标: 12

关注者: 10

分支: 8

开放问题: 9

类型:neos-package


README

扩展Neos后端登录以支持双因素认证。目前我们仅支持TOTP令牌。

计划支持WebAuthn!

此包的功能

Screen.Recording.2022-02-08.at.17.07.59.mov

此包允许所有用户注册他们的个人TOTP令牌(身份验证器应用)。作为管理员,您能够删除用户的令牌,以防他们自己将自己锁定。

Screenshot 2022-02-08 at 17 11 01

设置

强制执行2FA

要强制设置和使用2FA,您可以将以下内容添加到您的Settings.yaml中。

Sandstorm:
    NeosTwoFactorAuthentication:
        # enforce 2FA for all users
        enforceTwoFactorAuthentication: true

使用此设置,用户在设置第二个因素之前无法登录到CMS。

此外,您可以通过将以下内容添加到您的Settings.yaml中来强制特定身份验证提供程序和/或角色的2FA

Sandstorm:
    NeosTwoFactorAuthentication:
      # enforce 2FA for specific authentication providers
      enforce2FAForAuthenticationProviders : ['Neos.Neos:Backend']
      # enforce 2FA for specific roles
      enforce2FAForRoles: ['Neos.Neos:Administrator']  

发行者命名

要覆盖默认站点名称作为发行者标签,您可以通过配置设置定义一个

Sandstorm:
    NeosTwoFactorAuthentication:
        # (optional) if set this will be used as a naming convention for the TOTP. If empty the Site name will be used
        issuerName: ''

测试过的2FA应用

感谢@Sebobo @Benjamin-K创建支持并测试过的应用列表!

iOS:

  • Google Authenticator(用于开发)✅
  • Authy✅
  • Microsoft Authenticator✅
  • 1Password✅

Android:

  • Google Authenticator✅
  • Microsoft Authenticator✅
  • Authy✅

我们是如何做到的

  • 我们引入了一个新的中间件SecondFactorMiddleware,它基于Neos Session处理2FA。
    • 以下是SecondFactorMiddleware对任何请求进行的检查概述
                              ┌─────────────────────────────┐
                              │           Request           │
                              └─────────────────────────────┘
                                             ▼
                                  ... middleware chain ...
                                             ▼
                              ┌─────────────────────────────┐
                              │  SecurityEndpointMiddleware │
                              └─────────────────────────────┘
                                             ▼
              ┌───────────────────────────────────────────────────────────────────┐
              │                     SecondFactorMiddleware                        │
              │                                                                   │
              │  ┌─────────────────────────────────────────────────────────────┐  │
              │  │ 1. Skip, if no authentication tokens are present, because   │  │
              │  │    we're not on a secured route.                            │  │
              │  └─────────────────────────────────────────────────────────────┘  │
              │  ┌─────────────────────────────────────────────────────────────┐  │
              │  │ 2. Skip, if 'Neos.Backend:Backend' authentication token not │  │
              │  │    present, because we only support second factors for Neos │  │
              │  │    backend.                                                 │  │
              │  └─────────────────────────────────────────────────────────────┘  │
              │  ┌─────────────────────────────────────────────────────────────┐  │
              │  │ 3. Skip, if 'Neos.Backend:Backend' authentication token is  │  │
              │  │    not authenticated, because we need to be authenticated   │  │
              │  │    with the authentication provider of                      │  │
              │  │    'Neos.Backend:Backend' first.                            │  │
              │  └─────────────────────────────────────────────────────────────┘  │
              │  ┌─────────────────────────────────────────────────────────────┐  │
              │  │ 4. Skip, if second factor is not set up for account and not │  │
              │  │    enforced via settings.                                   │  │
              │  └─────────────────────────────────────────────────────────────┘  │
              │  ┌─────────────────────────────────────────────────────────────┐  │
              │  │ 5. Skip, if second factor is already authenticated.         │  │
              │  └─────────────────────────────────────────────────────────────┘  │
              │  ┌─────────────────────────────────────────────────────────────┐  │
              │  │ 6. Redirect to 2FA login, if second factor is set up for    │  │
              │  │    account but not authenticated.                           │  │
              │  │    Skip, if already on 2FA login route.                     │  │
              │  └─────────────────────────────────────────────────────────────┘  │
              │  ┌─────────────────────────────────────────────────────────────┐  │
              │  │ 7. Redirect to 2FA setup, if second factor is not set up for│  │
              │  │    account but is enforced by system.                       │  │
              │  │    Skip, if already on 2FA setup route.                     │  │
              │  └─────────────────────────────────────────────────────────────┘  │
              │  ┌─────────────────────────────────────────────────────────────┐  │
              │  │ X. Throw an error, because any check before should have     │  │
              │  │    succeeded.                                               │  │
              │  └─────────────────────────────────────────────────────────────┘  │
              └───────────────────────────────────────────────────────────────────┘
                                                ▼
                                       ... middlewares ...
       
      

当更新Neos时,这些部分可能会崩溃

  • 第二个因素的登录屏幕是Neos.Neos包中登录屏幕的硬拷贝
    • 只是将用户名/密码表单替换为第二个因素的表单
    • 可能需要在Neos更新时替换
  • 希望此包的其余部分足够坚固,足以应对下一个主要版本的Neos ;)

为什么不……?

增强UsernamePassword认证令牌

这实际上是1.0.5版本之前的做法。

这个问题是,我们希望用户通过PersistedUsernamePasswordProvider使用该令牌登录,但同时希望在2FA未经认证的情况下使用该令牌。我们发现很难在2FA强制执行但用户尚未启用第二个因素的情况下找到安全的2FA设置解决方案。

中间件方法在“登录”和“第二个因素认证”之间做出了明确的区分,同时仍然是基于会话的且无法绕过。

将认证策略设置为allTokens

AuthenticationProviderManager需要在同一时间授权所有令牌,否则它将抛出异常(参见AuthenticationProviderManager第181行

if ($this->authenticationStrategy === Context::AUTHENTICATE_ALL_TOKENS) {
    throw new AuthenticationRequiredException('Could not authenticate all tokens, but authenticationStrategy was set to "all".', 1222203912);
}

)

这导致了一个错误,其中AuthenticationProviderManager在用户能够输入任何凭据之前抛出异常。SecurityEntryPointMiddleware捕获这些异常并将用户重定向到Neos后端登录,这导致相同的异常再次发生。我们陷入了一个无限重定向的循环。

《Neos Flow 安全文档》(多因素认证策略)建议如何实现多因素认证,但这种方法看起来从未经过测试。在撰写本文时,似乎 authenticationStrategy: allTokens 标志已损坏且不可用。