marcinchus/secure-jwt-bundle

用于提高JWT安全性的工具包

0.0.11 2022-09-21 08:19 UTC

This package is auto-updated.

Last update: 2024-09-21 12:43:47 UTC


README

Symfony工具包,使JWT更安全

安装

安装过程可能不流畅且存在错误,但很容易解决

composer require connectholland/secure-jwt-bundle

安装后可能会出现错误

Cannot autowire service "ConnectHolland\SecureJWTBundle\EventSubscriber\LoginSubscriber": argument "$googleAuthenticator" of method "__construct()" references class "Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticator" but no such service exists.

配置scheb twofactor Google

scheb_two_factor.yaml文件中

scheb_two_factor:
    security_tokens:
        - Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
    google:
        enabled: true
        server_name: Secure Server
        issuer: Connect Holland
        digits: 6
        window: 1

再次运行

composer require connectholland/secure-jwt-bundle

以完成安装。

BTW1:在安装此工具包之前安装scheb twofactor工具包也可以防止此错误。
BTW2:当然,欢迎提交修复这些问题的PR :)

Cookie存储

本地存储中的令牌不安全,因此如果您从Web界面使用令牌,您应该将它们存储在其他地方。安全的Cookie是一个不错的选择。如下配置Cookie存储

让lexik/jwt-authentication-bundle查看Cookie

lexik_jwt_authentication.yaml配置文件中

lexik_jwt_authentication:
    secret_key: '%env(resolve:JWT_SECRET_KEY)%'
    public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
    pass_phrase: '%env(JWT_PASSPHRASE)%'

    token_extractors:
            # Default header auth, can be useful to allow for other auth types (for example /api)
            authorization_header:
                enabled: true

            # Make sure this is enabled
            cookie:
                enabled: true
                name:    BEARER
                set_cookies:
                    BEARER: ~

确保令牌设置为安全Cookie

security.yaml配置文件中

    login:
        pattern:  ^/api/login
        stateless: true
        anonymous: true
        json_login:
            check_path:               /api/login_check
            success_handler:          lexik_jwt_authentication.handler.authentication_success
            failure_handler:          lexik_jwt_authentication.handler.authentication_failure

使令牌失效

默认情况下,令牌在过期前有效。这使得无法真正注销。您可以配置令牌失效以允许注销

创建数据库表

doctrine.yaml文件中

doctrine:
    orm:
        mappings:
            ConnectHolland\SecureJWTBundle:
                is_bundle: true
                type: annotation
                dir: '%kernel.project_dir%/vendor/connectholland/secure-jwt-bundle/src/Entity'
                prefix: 'ConnectHolland\SecureJWTBundle\Entity'
                alias: SecureJWTBundle

并运行迁移

bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate -n

配置API端点注销

api_platform.yaml文件中

api_platform:
    mapping:
        paths: ['%kernel.project_dir%/vendor/connectholland/secure-jwt-bundle/src/Message']

当然,不要删除可能已在paths配置中存在的其他必需路径。

您的API中将有一个logout端点。此端点需要以下格式化的消息

{
  "logout": "some string"
}

注销的值不重要且不使用。此字段是必需的,因为API平台要求消息中至少有一个字段。(欢迎提供更好的解决方案)。

不允许失效的令牌

security.yaml文件中

    api:
        pattern: ^/api
        stateless: true
        anonymous: true
        guard:
            authenticators:
                - ConnectHolland\SecureJWTBundle\Security\Guard\JWTTokenAuthenticator

JWT中的双因素认证

配置Google身份验证器

scheb_two_factor.yaml文件中

scheb_two_factor:
    security_tokens:
        - Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
    google:
        enabled: true
        server_name: Secure Server
        issuer: Connect Holland
        digits: 6
        window: 1

使用two_factor_jwt安全监听器和提供程序

security.yaml文件中

    login:
        pattern:  ^/api/login
        stateless: true
        anonymous: true        
        two_factor_jwt:
            check_path:               /api/login_check
            success_handler:          ConnectHolland\SecureJWTBundle\Security\Http\Authentication\AuthenticationSuccessHandler
            failure_handler:          ConnectHolland\SecureJWTBundle\Security\Http\Authentication\AuthenticationFailureHandler

实现正确的接口

您的用户对象应实现ConnectHolland\SecureJWTBundle\Entity\TwoFactorUserInterface

使用2FA

curl -X POST http://host/api/users/authenticate -H 'Content-Type: application/json' -d '{"username": "username", "password": "password"}'

这将返回以下响应

{
  "result":"ok",
  "status":"two factor authentication required"
}

如果尚未设置2FA,您将收到

{
  "result":"ok",
  "message":"use provided QR code to set up two factor authentication",
  "qr":"QR code (data URL)"
}

在下一次调用中添加双因素挑战

curl -X POST http://host/api/users/authenticate -H 'Content-Type: application/json' -d '{"username": "username", "password": "password", "challenge": "123456"}'

如果正确,您将收到

{
  "result":"ok"
}

响应头将包括一个包含JWT令牌的安全Cookie,允许未来的认证调用。

2FA 记住此设备

记住设备功能允许用户在可配置的天数内跳过2FA。默认配置设置为false,这意味着在登录后不会设置REMEMBER_DEVICE cookie。默认天数设置为30。

配置

在根项目的config/packages文件夹中创建一个名为:connect_holland_secure_jwt.yaml的新文件

在此文件中可以设置配置

connect_holland_secure_jwt:
  is_remembered: true
  expiry_days: 14

如前所述,登录后,将设置REMEMBER_DEVICE cookie。它将包含一个Unix到期时间和用户的电子邮件。

除了放置cookie外,它还将保存在secure_jwt_remember_device_token表中。该实体可在src/Entity/RememberDeviceToken.php中找到

恢复代码

您可以检索用于2FA的恢复代码,允许您重置2FA。如果将有效的恢复代码作为challenge输入,则2FA将重置,并返回一个QR代码响应。