How to authenticate with MFA?

Estimated reading: 4 minutes 155 views

To use VG MFA, you need a VGMFA license.

What is the VGMFAAuthMode?

In Visual-Guard, it has 2 types of MFA authentication:

  • VGMagicLink, that sends a link to the validated user email. When the user clicks, that validates the authentication (Synchro System).
  • VGOTP, that sends to the user validated mobile number. User then enters the OTP and validates the authentication.

What is the VGMFATransportMode?

In Visual-Guard MFA, it has 2 transport mode:

  • SMS, that sends OTP/Link to the user for authentication
  • Email, that sends OTP/Link to the user for authentication

VG 2024.0 Sample

//Create or re-use existing VG Runtime
using (VGSecurityRuntime runtime = new VGSecurityRuntime(VGSecurityManager.Runtime))
{
    //Authenticate the user
    VGAuthenticationRequest request = new VGAuthenticationRequest(new VGNamePasswordCredential("<username>", "<password>"));
    VGAuthenticationResponse response = runtime.Authenticate(request);

    //If user need to enroll for MFA
    if (response.IsMFAEnrollmentRequired)
    {
        //Case: Enroll user's email address. Similary you can enroll mobile number
        var enrollRequest = new VGMFAEnrollmentRequest(request.RequestId, "<Email Address>");
        var enrollResponse = runtime.MFA.SendEmailVerification(enrollRequest);
        if (enrollResponse.Status == VGMFAEnrollmentStatus.Success)
        {
            //OTP received in email
            enrollRequest.SecureCode = "<OTP>";

            //Validate the OTP received in email
            var validResponse = runtime.MFA.ValidateEmail(enrollRequest);
            if (validResponse.Status == VGMFAEnrollmentStatus.Success)
            {
                return;
            }
        }
    }

    //If user need to authenticate with MFA before proceeding
    if (response.IsMFAAuthenticationRequired && null != response.MFAAvailables && 0 < response.MFAAvailables.Count)
    {
        //Select any one available MFA mode for authentication
        VGMFAAvailable selectedMFA = response.MFAAvailables.First();

        VGMFACredentialRequest mfaRequest = new VGMFACredentialRequest(selectedMFA.RequestId, selectedMFA.Id);
        mfaRequest = selectedMFA.GetMFACredential();

        VGAuthenticationRequest mfaAuthRequest = new VGAuthenticationRequest(mfaRequest);
        response = runtime.Authenticate(mfaAuthRequest);

        //In case of OTP mode
        if (response.IsMFAWaitingUserAction)
        {
            string readKey = Console.ReadLine();
            mfaRequest.SetOTP(readKey);

            request = new VGAuthenticationRequest(mfaRequest);
            response = runtime.Authenticate(request);                            
        }

        //Authenticated
        if (response.Status.HasFlag(VGAuthenticationStatus.Success))
        {

        }
    }
}

VG 2020.3 Sample

//Create or re-use existing VG Runtime
using (VGSecurityRuntime runtime = new VGSecurityRuntime(VGSecurityManager.Runtime))
{
    // In this case the VGPrincipal is already load, you want to ask MFA authentification 
    var status = runtime.Authenticate("<username>", "<password>", VGAuthenticationMode.VisualGuard);

    if (!status.IsFailed)
    {
        var auth = runtime.MFAAuthentication(VGMFATransportMode.SMS, VGMFAAuthMode.OTP);

        //MFA mode selected = OTP sent by SMS
        if (auth.IsUserAccountNotYetAvailable)
        {
            //If MFA not yet enabled, then Enable it by program
            runtime.MFA.ActiveMFA(runtime.Principal);
        }

        //The user don't have any any
        if (auth.HasUserAccountMissingEmail)
        {
            Console.WriteLine("Email not yet available ");
            //Set an email address
            runtime.MFA.SetEmail("<Email Address>");
        }

        //The user don't have any mobile phone
        if (auth.HasUserAccountMissingMobilePhone)
        {
            Console.WriteLine("Mobile number not yet available");
            //Set an a mobile number
            runtime.MFA.SetMobilePhone("< +xx Mobile Number>");
        }

        // The user need to provide an OTP 
        if (auth.IsMFAWaitingUserAction)
        {
            Console.WriteLine("Need OTP value:");
            var otp = Console.ReadLine();
            auth = runtime.MFAAuthentication(otp);
        }
    }
    else
    {
        //The status is failed
        if (status.IsMFAEnrollmentRequired)
        {
            if (status is VGAuthenticationResponse)
            {
                var response = (VGAuthenticationResponse)status;
                var mfaRequestId = response.AuthenticationEnrollmentRequest.Id;

                //Can we enroll ?
                var needToUseVGIdentityServerUIMode = false;
                if (needToUseVGIdentityServerUIMode)
                {
                    // Navigate to the url
                    // Browse this url : response.AuthenticationEnrollmentRequest.EnrollmentUrl
                    var nav = response.AuthenticationEnrollmentRequest.EnrollmentUrl;

                }
                else
                {
                    if (response.AuthenticationEnrollmentRequest.TransportModes.Contains(VGMFATransportMode.SMS))
                    {
                        Console.WriteLine("Enter a mobile number ");
                        var mobileNumber = Console.ReadLine();

                        var enrollRequest = new VGMFAEnrollmentRequest(mfaRequestId, mobileNumber);
                        var enrollResponse = runtime.MFA.SendMobileNumberVerification(enrollRequest);
                        if (enrollResponse.Status == VGMFAEnrollmentStatus.Success)
                        {
                            Console.WriteLine("Enter OTP: ");
                            var otp = Console.ReadLine();

                            //OTP received on Mobile number
                            enrollRequest.SecureCode = otp;

                            //Validate the OTP received in email
                            var validResponse = runtime.MFA.ValidateMobileNumber(enrollRequest);
                            if (validResponse.Status == VGMFAEnrollmentStatus.Success)
                            {
                                //User enrolled and need to re-authenticate with the username/password to proceed with the MFA authentication
                                return;
                            }
                        }
                    }
                    else if (response.AuthenticationEnrollmentRequest.TransportModes.Contains(VGMFATransportMode.Email))
                    {
                        Console.WriteLine("Enter an email ");
                        var email = Console.ReadLine();

                        var enrollRequest = new VGMFAEnrollmentRequest(mfaRequestId, email);
                        var enrollResponse = runtime.MFA.SendEmailVerification(enrollRequest);
                        if (enrollResponse.Status == VGMFAEnrollmentStatus.Success)
                        {
                            Console.WriteLine("Enter OTP: ");
                            var otp = Console.ReadLine();

                            //OTP received on email
                            enrollRequest.SecureCode = otp;

                            //Validate the OTP received in email
                            var validResponse = runtime.MFA.ValidateEmail(enrollRequest);
                            if (validResponse.Status == VGMFAEnrollmentStatus.Success)
                            {
                                //User enrolled and need to re-authenticate with the username/password to proceed with the MFA authentication
                                return;
                            }
                        }
                    }
                    else
                    {
                        throw new Exception("Don't support this mode");
                    }
                }
            }
        }
    }
}