Welcome Guest, Not a member yet? Register   Sign In
Shield - 2FA for only some users
#1
Information 

Hi all,
Thank you in advance for your help.
I am trying to find a way to only trigger the 2FA process for members of certain groups.
OR even better really:
If I add a table column for 2fa and the user has selected to do 2fa for their login.

How can I accomplish this?

Thank you,
Reply
#2

See https://github.com/codeigniter4/shield/discussions/525
Reply
#3

Thank you, Thats great help.
I will star that location to check for further questions and checking before asking.
Already helped with my SyncGroups not working.

I have just about got extending the Email2FA working.
Simply bypassing createIdentity() method doesn't seem to work,
I have to bypass the return view(setting('Auth.views')['action_email_2fa'], ['user' => $user]); as well.

However the Show() function requires a string to be returned, but if I want to redirect()->to() it fails as not a string.
if I removed the : String requirement it throws an error because I have to follow the parent (Email2FA) rules.

Can you help direct me a bit here?
Reply
#4

(This post was last modified: 10-04-2023, 11:57 AM by TexasTF.)

Hi,
Nevermind, I figured it out.
Thank you for your help @kenjis

Anyone who comes across this.
I added to my users table a column called email2fa
*Either 0 or 1*, 1 being they get 2fa.

Extended the Email2FA class

Override the createIdentify function as follows works:


Code:
public function createIdentity(User $user): string
    {
        if($user->email2fa != '1'){
            return '';
        }
        /** @var UserIdentityModel $identityModel */
        $identityModel = model(UserIdentityModel::class);

        // Delete any previous identities for action
        $identityModel->deleteIdentitiesByType($user, $this->type);

        $generator = static fn (): string => random_string('nozero', 6);

        return $identityModel->createCodeIdentity(
            $user,
            [
                'type'  => $this->type,
                'name'  => 'login',
                'extra' => lang('Auth.need2FA'),
            ],
            $generator
        );
    }
Reply
#5

(This post was last modified: 03-07-2024, 01:41 PM by elimariaaaa.)

(10-04-2023, 10:03 AM)TexasTF Wrote: Hi,
Nevermind, I figured it out.
Thank you for your help @kenjis

Anyone who comes across this.
I added to my users table a column called email2fa
*Either 0 or 1*, 1 being they get 2fa.

Extended the Email2FA class

Override the createIdentify function as follows works:


Code:
public function createIdentity(User $user): string
    {
        if($user->email2fa != '1'){
            return '';
        }
        /** @var UserIdentityModel $identityModel */
        $identityModel = model(UserIdentityModel::class);

        // Delete any previous identities for action
        $identityModel->deleteIdentitiesByType($user, $this->type);

        $generator = static fn (): string => random_string('nozero', 6);

        return $identityModel->createCodeIdentity(
            $user,
            [
                'type'  => $this->type,
                'name'  => 'login',
                'extra' => lang('Auth.need2FA'),
            ],
            $generator
        );
    }

Sorry for this newbie question. How do I extend this class? Currently, I directly added the code snippet to the actual file.
Reply
#6

All files under vendor/ directory is controlled by Composer.
You should not edit files in it.
All changes will be lost when you update the package.

Create a class that extends the Email2FA in somewhere under app/ directory.
And configure to use it for Authentication Actions:
https://github.com/codeigniter4/shield/b...#L100-L103
Reply
#7

So I added my file inside \App\Libraries and called it CustomEmail2FA.php.

Inside it is my code:
Code:
<?php

namespace App\Libraries;
use CodeIgniter\Shield\Authentication\Actions\Email2FA;

class CustomEmail2FA extends Email2FA{
    /**
    * Creates an identity for the action of the user.
    *
    * @return string secret
    */
    public function createIdentity(User $user): string
    {
        if($user->email2fa != '1'){
            return '';
        }
        /** @var UserIdentityModel $identityModel */
        $identityModel = model(UserIdentityModel::class);

        // Delete any previous identities for action
        $identityModel->deleteIdentitiesByType($user, $this->type);

        $generator = static fn (): string => random_string('nozero', 6);

        return $identityModel->createCodeIdentity(
            $user,
            [
                'type'  => $this->type,
                'name'  => 'login',
                'extra' => lang('Auth.need2FA'),
            ],
            $generator
        );
    }
}

Then I declared it in Auth.php:
Code:
public array $actions = [
        'register' => \CodeIgniter\Shield\Authentication\Actions\EmailActivator::class,
        'login'    => \App\Libraries\CustomEmail2FA::class,
    ];

Now, when I log in, I always get this error:
Quote:Call to a member function getType() on null

From this file:
Quote:VENDORPATH/codeigniter4/shield/src/Authentication/Authenticators/Session.php at line 486

Line 486:
Code:
$identity = $this->userIdentityModel->getIdentityByType($this->user, $action->getType());

What am I doing wrong?
Reply
#8

The error shows $action is null.
Reply
#9

Maybe you need to place the class in an "Actions" folder.
Reply
#10

Did you manage to get this working?
Reply




Theme © iAndrew 2016 - Forum software by © MyBB