<p>Alright so I was actually misunderstanding how modules work with craft and yii. The <code>init</code> function in your module actually fires before crafts core controllers do, so you could use that to do whatever you need to do before the request continues on. I'm coming from WordPress so I thought I had to 'hook' into something. Here's an example of how you would override the login action on a post request. In the real world you would probably want to extract this logic to a <code>Service</code> but for the sake of clarity I'm just putting it in the init function here.</p>

<p>So, I guess the way to override any core controller is to look for that url or action in your modules init function and do whatever you need to do to override it.</p>

<pre class="lang-php prettyprint-override"><code>namespace ldap;

use Craft;
use craft\elements\User;

class LdapModule extends \yii\base\Module
{
    public function init()
    {
        Craft::setAlias('@ldap', __DIR__);

        if (Craft::$app-&gt;getRequest()-&gt;getIsConsoleRequest()) {
            $this-&gt;controllerNamespace = 'ldap\\console\\controllers';
        } else {
            $this-&gt;controllerNamespace = 'ldap\\controllers';
        }

        parent::init();

        $isActionRequest = Craft::$app-&gt;getRequest()-&gt;getIsActionRequest();
        $isLoginAttempt = Craft::$app-&gt;getRequest()-&gt;getFullPath() === 'admin/actions/users/login';
        $isPostRequest = Craft::$app-&gt;getRequest()-&gt;getIsPost();

        if ($isLoginAttempt &amp;&amp; $isPostRequest &amp;&amp; $isActionRequest) {
            //...Ldap functionality and creating/activating new user if need be goes here. The request
            // will then continue on to crafts core UserController to log them in.

            // As an aside, if you want to create a user programmatically to login 
            // here's more or less how to do it.
            // @reference craft\controllers\UsersController.actionSaveUser
            $user = new User();
            $user-&gt;email = 'wolf@inyourface.com';
            $user-&gt;username = 'wolf';
            $user-&gt;firstName = 'Wolf';
            $user-&gt;lastName = 'Face';
            $user-&gt;pending = true;
            $user-&gt;newPassword = 'secret';
            if ($user-&gt;validate(null, false)) {
                Craft::$app-&gt;getElements()-&gt;saveElement($user, false);
                Craft::$app-&gt;getUsers()-&gt;activateUser($user);
                Craft::$app-&gt;getUserPermissions()-&gt;saveUserPermissions($user-&gt;id, ['accessCp']);
            }
        }
    }
}

</code></pre>

CC BY-SA 4.0
2020-02-19T16:25:35.490Z
2020-02-19T16:25:35.490Z
Myles Hyson
<p>Hi I'm trying to build a custom authentication plugin for an organization, and I'm having a hard time figuring out how to override the <code>craft\controllers\UserController.actionLogin</code> method. I tried hooking into <code>AuthenticateUserEvent</code> however this is fired <em>after</em> craft has already checked to see if a user exists. For our purposes we want to skip that entirely and solely use ldap to authenticate users. Here's ideally what I need to do.</p>

<ol>
<li>Check if the user with the given creds exists in ldap.</li>
<li>If so, and they don't exist in craft, create a new user with those same creds.</li>
<li>Forward the creds of the new or existing user to <code>craft\controllers\UserController.actionLogin</code> to finish logging them in to the admin panel.</li>
</ol>

<p>Essentially I need to override that controller action and I can't find in the docs how to go about doing that. It also doesn't seem possible to override the login form template either? I realize if I could override that template then I can just call my own controller action.</p>

<p>Thanks for any help you can give!</p>

<templating><login><controller><authentication>
How to override UserController.actionLogin or the login form template in Craft 3?
# How to override UserController.actionLogin or the login form template in Craft 3?

(Asked by: username_0 on 2020-02-18)

Hi I'm trying to build a custom authentication plugin for an organization, and I'm having a hard time figuring out how to override the `craft\controllers\UserController.actionLogin` method. I tried hooking into `AuthenticateUserEvent` however this is fired *after* craft has already checked to see if a user exists. For our purposes we want to skip that entirely and solely use ldap to authenticate users. Here's ideally what I need to do.

1. Check if the user with the given creds exists in ldap.
2. If so, and they don't exist in craft, create a new user with those same creds.
3. Forward the creds of the new or existing user to `craft\controllers\UserController.actionLogin` to finish logging them in to the admin panel.

Essentially I need to override that controller action and I can't find in the docs how to go about doing that. It also doesn't seem possible to override the login form template either? I realize if I could override that template then I can just call my own controller action.

Thanks for any help you can give!

**Tags:** templating, login, controller, authentication


---

## 1 answers

### Answer by username_0 on 2020-02-19. Score: 2 | Accepted answer

Alright so I was actually misunderstanding how modules work with craft and yii. The init function in your module actually fires before crafts core controllers do, so you could use that to do whatever you need to do before the request continues on. I'm coming from WordPress so I thought I had to 'hook' into something. Here's an example of how you would override the login action on a post request. In the real world you would probably want to extract this logic to a Service but for the sake of clarity I'm just putting it in the init function here.
So, I guess the way to override any core controller is to look for that url or action in your modules init function and do whatever you need to do to override it.
namespace ldap;

use Craft;
use craft\elements\User;

class LdapModule extends \yii\base\Module
{
    public function init()
    {
        Craft::setAlias('@ldap', __DIR__);

        if (Craft::$app->getRequest()->getIsConsoleRequest()) {
            $this->controllerNamespace = 'ldap\\console\\controllers';
        } else {
            $this->controllerNamespace = 'ldap\\controllers';
        }

        parent::init();

        $isActionRequest = Craft::$app->getRequest()->getIsActionRequest();
        $isLoginAttempt = Craft::$app->getRequest()->getFullPath() === 'admin/actions/users/login';
        $isPostRequest = Craft::$app->getRequest()->getIsPost();

        if ($isLoginAttempt && $isPostRequest && $isActionRequest) {
            //...Ldap functionality and creating/activating new user if need be goes here. The request
            // will then continue on to crafts core UserController to log them in.

            // As an aside, if you want to create a user programmatically to login 
            // here's more or less how to do it.
            // @reference craft\controllers\UsersController.actionSaveUser
            $user = new User();
            $user->email = 'wolf@inyourface.com';
            $user->username = 'wolf';
            $user->firstName = 'Wolf';
            $user->lastName = 'Face';
            $user->pending = true;
            $user->newPassword = 'secret';
            if ($user->validate(null, false)) {
                Craft::$app->getElements()->saveElement($user, false);
                Craft::$app->getUsers()->activateUser($user);
                Craft::$app->getUserPermissions()->saveUserPermissions($user->id, ['accessCp']);
            }
        }
    }
}


---

