Coder Social home page Coder Social logo

magetarian / customertwofactorauth Goto Github PK

View Code? Open in Web Editor NEW
7.0 3.0 3.0 300 KB

Two Factor Authentication for Customers

License: GNU General Public License v3.0

PHP 80.59% HTML 5.33% JavaScript 13.97% Less 0.12%
magento2 magento2-module 2fa-security login tfa two-factor-authentication authy google-authenticator duo-security

customertwofactorauth's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

customertwofactorauth's Issues

Admin changes forced providers

When customer had configured provider like Google and customer exclude it from the list:

Steps to reproduce

  1. Admin Configured 2FA Forced Providers With Google and Duo
  2. Customer logs in and forced to use 2FA with Google and configured only Google
  3. Admin changed 2FA setting to force only Duo
  4. Customer logs in.....

Actual result:

Customer wont be able to login with google because admin excluded it from the list and will land back to login page.

Expected result:

Customer's selection and configuration of 2FA should be updated - in this case Google should be removed if selected with according config

Login-callbacks should be invoked in failure situations

If there is an error during the login within Magento's authentication-popup modal, the loader will not disappear. The reason for this problem is that, the callbacks registered with registerLoginCallback() are not invoked from the mixin.

I think the callbacks should be invoked in failure path 1 and failure path 2.

This behaviour would also match the one from Magento: https://github.com/magento/magento2/blob/2.4-develop/app/code/Magento/Customer/view/frontend/web/js/action/login.js

Admin: Remove List of providers for a single customer

This list doesn't make sense - it just show customer's selection.
Instead of it will be a button to reset providers (it will empty customer's selection and config)
#42

This attribute makes sense for a customer - it save customer's choice for 2FA and limit customer to sign in using this method only.

Authy - Workflow. Implementation

Configuration
Stores -> Configuration->Security->2FA:
Enable for Customers and Enable Authy.
[FE] Customer ->2FA tab -> Enable Authy

Workflow

Customer Login -> Username/Password verified

Before Magento sets customer as logged in there suppose to be QR code and text field for Authy and validation code.

Once the validation code entered based on validation result customer logs in or error message shown.

Screenshot_4

Screenshot_5

Screenshot_7

Screenshot_8

Screenshot_9

Google Authenticator - Workflow. Implementation

Configuration
Stores -> Configuration->Security->2FA: Enable for Customers and Enable Google Authenticator.
[FE] Customer ->2FA tab -> Enable Google Authenticator

Workflow

  1. Customer Login -> Username/Password verified
  2. Before Magento sets customer as logged in there suppose to be QR code and text field for Google Athenticator number and validation code.
  3. Once the validation code entered based on validation result customer logs in or error message shown.
    image

Unable to complete GA setup because no field to insert TOTP code to confirm

Install 1.1 via composer (see below for details) on clean install of Luma Store 2.4.0...
Configure enable GA for Customer = yes
Frontend Create customer account, logout
Login to customer account, enable for TFA/GA
Unable to complete GA setup because no field to insert TOTP code to confirm
However subsequent attempts to login to customer account fail, even with correct password and/or password reset

no-confirm-code

Install TFA 1.1


dotDEV:~/www/current$ composer require --update-no-dev magetarian/module-customer-tfa
Using version ^1.1 for magetarian/module-customer-tfa
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies
Package operations: 1 install, 0 updates, 0 removals
  - Installing magetarian/module-customer-tfa (1.1.0): Downloading (100%)
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.                                            
Writing lock file
Generating autoload files
37 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
dotDEV:~/www/current$ php7.4 -f bin/magento module:enable --clear-static-content Magetarian_CustomerTwoFactorAuth                                                   
The following modules have been enabled:
- Magetarian_CustomerTwoFactorAuth

To make sure that the enabled modules are properly registered, run 'setup:upgrade'.
Cache cleared successfully.
Generated classes cleared successfully. Please run the 'setup:di:compile' command to generate classes.                                                    
Generated static view files cleared successfully.
dotDEV:~/www/current$ ~/rebuild-M24.sh
+ echo Rebuilding Magento 2.4
Rebuilding Magento 2.4
+ cat /etc/centos-release
CentOS Linux release 7.8.2003 (Core)
+ /usr/local/apache/bin/httpd -v
Server version: Apache/2.4.46 (Unix)
Server built:   Aug 11 2020 14:47:55
+ mysql -V
mysql  Ver 14.14 Distrib 5.7.31, for Linux (x86_64) using  EditLine wrapper
+ php74 -v
PHP 7.4.8 (cli) (built: Aug 11 2020 15:03:47) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.8, Copyright (c), by Zend Technologies
+ php74 /usr/local/bin/composer -V
Composer version 1.10.10 2020-08-03 11:35:19
+ curl -s -XGET http://localhost:9200
+ grep 'cluster_name\|number'
+ xargs -n2 '-d\n'
  "cluster_name" : "elasticsearch",     "number" : "7.8.1",
+ cd /home/dotdev/www/current
+ php7.4 bin/magento --no-ansi maintenance:enable
Enabled maintenance mode
+ rm -rf pub/static/_requirejs var/view_preprocessed pub/static/frontend/ pub/static/adminhtml/ generated/code/
+ find var generated vendor pub/static pub/media app/etc -type f -exec chmod u+w '{}' +
+ find var generated vendor pub/static pub/media app/etc -type d -exec chmod u+w '{}' +
+ chmod o-rwx app/etc/env.php
+ chmod a+x bin/magento
+ php7.4 bin/magento --quiet --no-ansi setup:upgrade
Reading /home/dotdev/www/current/composer.json
Loading config file /home/dotdev/.config/composer/auth.json
Loading config file /home/dotdev/www/current/composer.json
Checked CA file /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem: valid
Reading /home/dotdev/.config/composer/composer.json
Loading config file /home/dotdev/.config/composer/auth.json
Loading config file /home/dotdev/.config/composer/composer.json
Loading config file /home/dotdev/.config/composer/auth.json
Reading /home/dotdev/.config/composer/auth.json
Reading /home/dotdev/www/current/vendor/composer/installed.json
Reading /home/dotdev/www/current/composer.lock
Checking for "magento/composer-root-update-plugin: 1.0.0" for the Web Setup Wizard...
Reading /home/dotdev/www/current/var/vendor/magento/composer-root-update-plugin/composer.json
Loading config file /home/dotdev/.config/composer/auth.json
Loading config file /home/dotdev/www/current/var/vendor/magento/composer-root-update-plugin/composer.json
No Web Setup Wizard update needed for magento/composer-root-update-plugin; version 1.0.0 is already in /home/dotdev/www/current/var. 
+ php7.4 bin/magento --quiet --no-ansi setup:di:compile
+ php7.4 bin/magento --quiet --no-ansi setup:static-content:deploy -f
+ php7.4 bin/magento --quiet --no-ansi indexer:reindex
+ php7.4 bin/magento --no-ansi deploy:mode:set developer
Enabled developer mode.
+ php7.4 bin/magento --quiet --no-ansi cache:enable
+ php7.4 bin/magento --quiet --no-ansi cache:clean
+ php7.4 bin/magento --quiet --no-ansi cache:flush
+ php7.4 bin/magento --no-ansi maintenance:disable
Disabled maintenance mode
+ php7.4 bin/magento --no-ansi cron:run
Ran jobs by schedule.
+ echo 'Done!'
Done!
+ exit
dotDEV:~/www/current$

Customer: Force 2FA configuration after Login/Registration

When admin setting to force 2FA set

  • Customer Logged In without 2FA -> forced to select & configure 2FA
  • Customer Registered -> forced to select & configure 2FA
  • Customer Registered at the order success screen -> forced to select & configure 2FA

Duo Security - Workflow. Implementation.

Configuration
Stores -> Configuration->Security->2FA: Enable for Customers and Enable Duo Security (Web SDK).
[FE] Customer ->2FA tab -> Enable Google Authenticator (#2)

Workflow

  1. Customer Login -> Username/Password verified
  2. Before Magento sets customer as logged another screen showed with iFrame from Duo.
    The iframe will do initial setup if need and 2FA validation - https://duo.com/docs/duoweb#4.-call-verify_response()
  3. Once the validation code entered based on validation result customer logs in or error message shown.

image

Handle EAV cache clean once the providers are enabled or disabled

Need to update the eav cache for the provider customer attribute option, so that once the system configuration for the 2FA setting for the customer are updated the attribute options should reflect the changes in:

  • Customer Adminhtml form
  • Frontend 2FA customer settings

Compatibility with M2.4.0

Fails to install with M2.4.0

$ composer require magetarian/module-customer-tfa

[InvalidArgumentException]
Package magetarian/module-customer-tfa at version has a PHP requirement incompatible
with your PHP version (7.4.8)

$ cat /etc/centos-release && /usr/local/apache/bin/httpd -v && mysql -V && php74 -v && php74 /usr/local/bin/composer -V && curl -s -XGET 'http://localhost:9200' | grep 'cluster_name|number' | xargs -n2 -d'\n'
CentOS Linux release 7.7.1908 (Core)
Server version: Apache/2.4.41 (Unix)
Server built: Feb 4 2020 20:56:27
mysql Ver 14.14 Distrib 5.7.29, for Linux (x86_64) using EditLine wrapper
PHP 7.4.8 (cli) (built: Jul 30 2020 16:50:16) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.8, Copyright (c), by Zend Technologies
Composer version 1.10.5 2020-04-10 11:44:22
"cluster_name" : "elasticsearch", "number" : "7.8.0",

Customer 2FA options Attribute

Create an attribute for customer where will be stored selection of 2FA providers. (Multi Select)

  • #2 Will be used to modify this value as customer

  • #9 will be used to modify this value as Admin

Reset Customer TFA not work

Describe the bug
Customer "Reset TFA" does not work. Customer Can't login without valid TFA.
I thought "Reset TFA" (Admin/customer) does set the 2FA-Provider for the customer to "none", same as new customer without setting 2FA.

To Reproduce
Magento 2.4.3-p1

Customer Login Entry Pages

Lets collect here pages where customer can login that we were able to implement new workflow at all pages and test it later.

  • Login form at the /customer/account/login
    • Google
    • Duo
    • Authy
  • Login form at the checkout
    • Google
    • Duo
    • Authy
  • Login modal form at the checkout
    • Google
    • Duo
    • Authy
  • Authentication Modal (When checkout only for logged in)
    • Google
    • Duo
    • Authy

PhpMd

Run vendor/bin/phpmd app/code/Magetarian/CustomerTwoFactorAuth/ text dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml

  • Magetarian/CustomerTwoFactorAuth/Controller/Customer/Providers.php:84 The method execute() has a Cyclomatic Complexity of 10. The configured cyclomatic complexity threshold is 10.

  • Magetarian/CustomerTwoFactorAuth/Plugin/Customer/Controller/Ajax/LoginPlugin.php:89 The method aroundExecute() has a Cyclomatic Complexity of 12. The configured cyclomatic complexity threshold is 10.

  • Magetarian/CustomerTwoFactorAuth/Plugin/Customer/Controller/Ajax/LoginPlugin.php:89 The method aroundExecute() has an NPath complexity of 264. The configured NPath complexity threshold is 200.

Login does not work in popup in Magento 2.4.1

Describe the bug
Login on domain.com/de/customer/account/login/ works great, but the login from within the popup (mini-cart "proceed to checkout" and cart "proceed to checkout") does not work (loader does not disappear).

To Reproduce
Steps to reproduce the behavior:

  1. Install Magento 2.4.1
  2. Add product to cart
  3. Go to cart
  4. Click on "proceed to checkout"
  5. Wait for popup to open
  6. Insert login data
  7. Loader does not disappear

Expected behavior
Loader must disappear so I can click on "Login using Google Authenticator"

Screenshots
Screenshot 2021-02-10 at 15 17 32

Desktop:

  • OS: macOS
  • Browser Chrome
  • Version 88.0.4324

Smartphone:

  • Device: iPhone6
  • OS: iOS12.5.1
  • Browser stock browser

Additional context

  • Magento 2.4.1
  • Guest checkout is disabled

Admin> Customer > All Customers section returns exception.

Immediately following installation via composer on 2.4.0
From Admin backend navigating to Admin> Customer > All Customers section returns exception.

1 exception(s):
Exception #0 (ReflectionException): Class Magetarian\CustomerTwoFactorAuth\Model\Config\Source\EnabledProviders does not exist

Exception #0 (ReflectionException): Class Magetarian\CustomerTwoFactorAuth\Model\Config\Source\EnabledProviders does not exist
<pre>#1 Magento\Framework\Code\Reader\ClassReader->getConstructor() called at [vendor/magento/framework/ObjectManager/Definition/Runtime.php:54]
#2 Magento\Framework\ObjectManager\Definition\Runtime->getParameters() called at [vendor/magento/framework/ObjectManager/Factory/Compiled.php:100]
#3 Magento\Framework\ObjectManager\Factory\Compiled->create() called at [vendor/magento/framework/ObjectManager/ObjectManager.php:56]
#4 Magento\Framework\ObjectManager\ObjectManager->create() called at [vendor/magento/framework/Validator/UniversalFactory.php:36]
#5 Magento\Framework\Validator\UniversalFactory->create() called at [vendor/magento/module-eav/Model/Entity/Attribute/AbstractAttribute.php:642]
#6 Magento\Eav\Model\Entity\Attribute\AbstractAttribute->getSource() called at [vendor/magento/module-customer/Model/AttributeMetadataConverter.php:98]
#7 Magento\Customer\Model\AttributeMetadataConverter->createMetadataAttribute() called at [vendor/magento/module-customer/Model/Metadata/CustomerMetadata.php:87]
#8 Magento\Customer\Model\Metadata\CustomerMetadata->getAttributeMetadata() called at [vendor/magento/module-customer/Model/Metadata/CustomerMetadata.php:119]
#9 Magento\Customer\Model\Metadata\CustomerMetadata->getAllAttributesMetadata() called at [vendor/magento/module-customer/Model/Metadata/CachedMetadata.php:85]
#10 Magento\Customer\Model\Metadata\CachedMetadata->getAllAttributesMetadata() called at [vendor/magento/module-customer/Ui/Component/Listing/AttributeRepository.php:83]
#11 Magento\Customer\Ui\Component\Listing\AttributeRepository->getList() called at [vendor/magento/module-customer/Ui/Component/Listing/Columns.php:112]
#12 Magento\Customer\Ui\Component\Listing\Columns->prepare() called at [vendor/magento/framework/View/Layout/Generator/UiComponent.php:164]
#13 Magento\Framework\View\Layout\Generator\UiComponent->prepareComponent() called at [vendor/magento/framework/View/Layout/Generator/UiComponent.php:161]
#14 Magento\Framework\View\Layout\Generator\UiComponent->prepareComponent() called at [vendor/magento/framework/View/Layout/Generator/UiComponent.php:142]
#15 Magento\Framework\View\Layout\Generator\UiComponent->generateComponent() called at [vendor/magento/framework/View/Layout/Generator/UiComponent.php:103]
#16 Magento\Framework\View\Layout\Generator\UiComponent->process() called at [vendor/magento/framework/View/Layout/GeneratorPool.php:81]
#17 Magento\Framework\View\Layout\GeneratorPool->process() called at [vendor/magento/framework/View/Layout.php:352]
#18 Magento\Framework\View\Layout->generateElements() called at [generated/code/Magento/Framework/View/Layout/Interceptor.php:89]
#19 Magento\Framework\View\Layout\Interceptor->generateElements() called at [vendor/magento/framework/View/Layout/Builder.php:129]
#20 Magento\Framework\View\Layout\Builder->generateLayoutBlocks() called at [vendor/magento/framework/View/Page/Builder.php:55]
#21 Magento\Framework\View\Page\Builder->generateLayoutBlocks() called at [vendor/magento/framework/View/Layout/Builder.php:65]
#22 Magento\Framework\View\Layout\Builder->build() called at [vendor/magento/framework/View/Layout.php:259]
#23 Magento\Framework\View\Layout->build() called at [vendor/magento/framework/View/Layout.php:884]
#24 Magento\Framework\View\Layout->getBlock() called at [generated/code/Magento/Framework/View/Layout/Interceptor.php:414]
#25 Magento\Framework\View\Layout\Interceptor->getBlock() called at [vendor/magento/module-backend/Model/View/Result/Page.php:26]
#26 Magento\Backend\Model\View\Result\Page->setActiveMenu() called at [vendor/magento/module-customer/Controller/Adminhtml/Index/Index.php:28]
#27 Magento\Customer\Controller\Adminhtml\Index\Index->execute() called at [vendor/magento/framework/Interception/Interceptor.php:58]
#28 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->___callParent() called at [vendor/magento/framework/Interception/Interceptor.php:138]
#29 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/framework/App/Action/Plugin/ActionFlagNoDispatchPlugin.php:51]
#30 Magento\Framework\App\Action\Plugin\ActionFlagNoDispatchPlugin->aroundExecute() called at [vendor/magento/framework/Interception/Interceptor.php:135]
#31 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#32 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->___callPlugins() called at [generated/code/Magento/Customer/Controller/Adminhtml/Index/Index/Interceptor.php:26]
#33 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->execute() called at [vendor/magento/framework/App/Action/Action.php:111]
#34 Magento\Framework\App\Action\Action->dispatch() called at [vendor/magento/module-backend/App/AbstractAction.php:151]
#35 Magento\Backend\App\AbstractAction->dispatch() called at [vendor/magento/framework/Interception/Interceptor.php:58]
#36 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->___callParent() called at [vendor/magento/framework/Interception/Interceptor.php:138]
#37 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/module-backend/App/Action/Plugin/Authentication.php:143]
#38 Magento\Backend\App\Action\Plugin\Authentication->aroundDispatch() called at [vendor/magento/framework/Interception/Interceptor.php:135]
#39 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#40 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->___callPlugins() called at [generated/code/Magento/Customer/Controller/Adminhtml/Index/Index/Interceptor.php:39]
#41 Magento\Customer\Controller\Adminhtml\Index\Index\Interceptor->dispatch() called at [vendor/magento/framework/App/FrontController.php:186]
#42 Magento\Framework\App\FrontController->processRequest() called at [vendor/magento/framework/App/FrontController.php:118]
#43 Magento\Framework\App\FrontController->dispatch() called at [vendor/magento/framework/Interception/Interceptor.php:58]
#44 Magento\Framework\App\FrontController\Interceptor->___callParent() called at [vendor/magento/framework/Interception/Interceptor.php:138]
#45 Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#46 Magento\Framework\App\FrontController\Interceptor->___callPlugins() called at [generated/code/Magento/Framework/App/FrontController/Interceptor.php:26]
#47 Magento\Framework\App\FrontController\Interceptor->dispatch() called at [vendor/magento/framework/App/Http.php:116]
#48 Magento\Framework\App\Http->launch() called at [vendor/magento/framework/App/Bootstrap.php:263]
#49 Magento\Framework\App\Bootstrap->run() called at [index.php:39]
</pre>

Enhanced Login form

Add an ability to replace current login form with enhanced one which supports 2FA.
or UIComponent same as Checkout

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.