---
title: Handling custom multi-factor authentication
related:
  - https://docs.kentico.com/13/custom-development/handling-global-events.md
  - https://docs.kentico.com/13/managing-users/user-registration-and-authentication/configuring-multi-factor-authentication.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

You can use [global events](https://docs.kentico.com/13/custom-development/handling-global-events.md) to define custom actions that the system performs after a user tries to sign in to the Xperience administration interface with [multi-factor authentication](https://docs.kentico.com/13/managing-users/user-registration-and-authentication/configuring-multi-factor-authentication.md) enabled. See the **SecurityEvents** section of the [global event reference](https://docs.kentico.com/13/custom-development/handling-global-events/reference-global-system-events.md#securityevents) to learn more about the available options.

> **Note:** When implementing a custom authentication factor, disable the **Display secret key** option in **Settings** **-> Security & Membership -> Authentication**.

To set up a custom action that the system performs after a user signs with multi-factor authentication enabled, implement a handler for the **SecurityEvents.MultiFactorAuthenticate.Execute** event. For example, you can implement functionality that sends users an SMS text or email with a passcode.

The following code is an example of a [custom module class](https://docs.kentico.com/13/custom-development/creating-custom-modules/initializing-modules-to-run-custom-code.md) that sends an email with a valid passcode to users who attempt to sign in with multi-factor authentication enabled.

```csharp

using CMS;
using CMS.DataEngine;
using CMS.Membership;
using CMS.EmailEngine;

// Registers the custom module into the system
[assembly: RegisterModule(typeof(CustomMFAuthenticationModule))]

public class CustomMFAuthenticationModule : Module
{
    // Module class constructor, the system registers the module under the name "CustomMFAuthentication"
    public CustomMFAuthenticationModule()
        : base("CustomMFAuthentication")
    {
    }

    // Contains initialization code that is executed when the application starts
    protected override void OnInit()
    {
        base.OnInit();

        // Assigns a handler to the SecurityEvents.MultiFactorAuthenticate.Execute event
        // This event occurs when users try to sign in with multi-factor authentication enabled
        SecurityEvents.MultiFactorAuthenticate.Execute += MFAuthentication_Execute;
    }

    // Handler method that sends the passcode emails
    // You can replace it with your custom code
    private void MFAuthentication_Execute(object sender, AuthenticationEventArgs e)
    {
        // Gets the user's email address
        string userEmail = e.User.Email;

        if (userEmail != null && userEmail != "")
        {
            // Creates the email message
            EmailMessage msg = new EmailMessage();

            msg.From = "system@localhost.local";
            msg.Recipients = userEmail;
            msg.Subject = "Authentication passcode";
            msg.Priority = EmailPriorityEnum.High;
            msg.Body = "<html><body><p>Your authentication passcode: "
                       + e.Passcode + " (valid for 5 minutes)"
                       + "</p></body></html>";

            // Sends out the email message
            EmailSender.SendEmail(msg);
        }
    }
}

```

> **Info:** When the multi-factor authentication event occurs, the system generates a valid passcode for the given user. You can access the passcode in the **Passcode** property of the handler's **AuthenticationEventArgs** parameter, and use any type of API to deliver the information to the authenticating user.
