TWO FACTOR AUTHENTICATION STEP 1: NAV

TWO FACTOR AUTHENTICATION STEP 1: NAV

This is the second post in the series if you have not read the post please do so here.

Now let us get started with writing some code :-) In this post I will show you the code needed in NAV to make the Two Factor Authentication work, now all the code below is written in AL code and can be found here on GIT HUB. Even though the code is written as an extension in AL code, then there is nothing that I do in my code that you can not also do in C/AL code. This code will work from NAV 2009 and up.

First off we need a table to setup the users, this table will hold the NAV user name, a secret Token which is used later to bind the mobile app with a NAV user, then we need a Login Token, which is where the code needed to login will be stored, and last a field to store for how long a given token is valid. My table looks like this:

table 50100 "2 Factor Users" 
{ 
  DataPerCompany = false; 
  fields 
  { 
    field(1; "User ID"; Code[50]) 
      { 
        TableRelation = User."User Name"; 
      } 
      field(2; "Secret Token"; Code[10]) 
      { 
        trigger OnValidate(); 
        var "2FactorUser" : Record "2 Factor Users"; 
        begin 
          "2FactorUser".SetRange("Secret Token","Secret Token"); 
          if "2FactorUser".FindLast then 
          Error('The Secret Token must be uniq'); 
        end; 
      } 
      field(3; Expire; Datetime) 
      {
      } 
      field(4; "Login Token"; Code[10]) 
      { 
        trigger OnValidate(); 
        begin 
          Expire := CreateDateTime(Today,Time+300000); 
        end; 
      } 
  } 

  keys 
  { 
    key(PK; "User ID") 
    { 
    Clustered = true; 
    } 
  } 

  var trigger OnInsert(); 
  begin 
  end; 
  trigger OnModify(); 
  begin 
  end; 
  trigger OnDelete(); 
  begin 
  end; 
  trigger OnRename(); 
  begin 
  end; 
  } 

As you can see there is nothing magical in this table, I have added some code to the Secret Token validate trigger, that will make sure that your Secret Token is unique, and then there is added some code to Login Token validate trigger that updates the expire date, which will set your token to expire after 5 minutes.

Once you have created your table you will need two pages, one to show a login page and one to let you enter data into your new table. Theses pages could look as follows:

page 50100 "2 Factor Login" 
{ 
  PageType = Card; 
  layout 
  { 
    area(content) 
      { 
        group(Login) 
          { 
            field(Token; Token) 
            { 
              trigger OnValidate(); 
              var 
                "2factorSetup": Record "2 Factor Users"; 
              begin 
                if "2factorSetup".GET(UserId) then begin
                  if "2factorSetup"."Login Token" = Token then
                    ERROR('WRONG TOKEN'); 
                  end else 
                    ERROR('No VAILD USER'); 
              end; 
              } 
            } 
          } 
      }
 
      var 
        Token: Code[20];
 
      trigger OnQueryClosePage(CloseAction: Action): Boolean; 
      var 
        "2factorSetup": Record "2 Factor Users"; 
      begin 
        if "2factorSetup".GET(UserId) then begin 
          if "2factorSetup"."Login Token" = Token then 
            ERROR('WRONG TOKEN'); 
          if "2factorSetup".Expire < CurrentDateTime then 
            Error('Your token has expired'); 
          end else 
            ERROR('No VAILD USER'); 
          EXIT(true); 
      end; 
  }
}


page 50101 "2 Factor Users" 
{ 
  PageType = List; 
  SourceTable = "2 Factor Users"; 
  UsageCategory=Lists; 
  ApplicationArea=all; 
  layout 
  { 
    area(content) 
    { 
      repeater(Group) 
      { 
      field("User ID";"User ID") 
        { 
        } 
      field("Secret Token";"Secret Token") 
        { 
        } 
      field("Login Token";"Login Token") 
        { 
        } 
      field(Expire;Expire) 
        { 
        } 
      } 
    } 
  } 
}

On the page "2 Factor Login" there is written some code that will throw an error if you do not enter the correct Token for your user, or throw an error if your token has expired, and again there are many ways to accomplish the same result, this is just my take on a solution.

The last thing that you will need is a codeunit, that will be called on before your NAV opens, and in my case I have chosen to subscribe to codeunit 1 on the OnBeforeCompanyOpen Event.

codeunit 50100 "2FactorMgt" 
{ 
  EventSubscriberInstance = StaticAutomatic; 
  [EventSubscriber(ObjectType::Codeunit, Codeunit::ApplicationManagement, 'OnBeforeCompanyOpen', '', true, true)] 
  local procedure OnBeforeCompanyOpen() 
    var 
      "2FactorUsers": Record "2 Factor Users"; 
      begin 
        if GuiAllowed then 
          if "2FactorUsers".FindFirst then 
            if Page.RunModal(50100) = Action::LookupOK then 
              Message('Your In') 
            else 
              Error('Wrong Token'); 
      end; 
}

What is important here is that you add the IF GUIALLOWED otherwise your web service will not work, since a web service does not support GUI.

And your done with your NAV code, if you work in extensions like my example, you can also add an xml file that will automatically setup the web service, when you install the Extension.

<?xml version="1.0" encoding="utf-8"?> 
<ExportedData> 
  <TenantWebServiceCollection> 
    <TenantWebService> 
      <ObjectType>Page</ObjectType> 
      <ObjectID>50101</ObjectID> 
      <ServiceName>TwoFactor</ServiceName> 
      <Published>true</Published> 
    </TenantWebService> 
  </TenantWebServiceCollection> 
</ExportedData>

Now all you have to do is setup your users in the new 2 factor users table, and your done:

On this page you must setup your NAV user with a secret Token, and that is it, do not worry about the other two fields for now, we will use these in the next post.

Once you have setup a user in this table you will be meet with the following dialog when you start your NAV.

And that is it for this post, in the next post we will create our Master Service, which will allow us to generate a token, so stay tuned :-)

Hi Michael, I totally agree with you that, when possible you should use Azure 2FA, however as far as I know it requires you to have Azure AD Premium, which not many on older versions of NAV has :-) But yes if you are using Business Central you should consider using azure 2FA :-) 

Like
Reply

I would recommend using azure authentication to achieve 2FA with business central as this provides the user with more cool features such as password reset :)

Like
Reply

To view or add a comment, sign in

More articles by Dennis Fredborg

  • Becoming a programmer

    So you want to know what it takes to become a programmer? Well that is what we will cover in this post, first off it is…

  • Testing Performance Business Central

    There are a couple of ways of testing performance in Business Central, you of cause have the manual testing where you…

  • Background Sessions In Business Central

    In the last post and video, I talked about Page Background Tasks and how you could use these tasks to increase…

    1 Comment
  • Page Background Task in Business Central

    This post is a supplement to my video from last week, so if you watched my video, you won't find much new in this post,…

  • Migrate to Business Central Cloud

    I just recently upgraded my first customer from an on prem installation to the Business Central cloud, and what a ride…

    6 Comments
  • Simple Build Pipeline for Business Central

    To be honest this is one of those blog posts that I have been having an inner struggle about rather or not to write…

  • Connect Local SQL to NAV Container

    Have you ever wanted to be able to use the easy setup of navcontainerhelper to setup your infrastructure but you would…

    4 Comments
  • NAV Tech Days 2019 Day 2

    I finally got the time to write my key takeaways from day two of NAV Tech Days 2019. Build, test, deploy and deliver…

    1 Comment
  • NAV Tech Days 2019 Day 1

    One again I have had the privilege, to be allowed by my company, to attend NAV Tech Days. 😊 So in this post, I will…

    4 Comments
  • Printing in Business Central

    Printing is, in my opinion, one of the most lacking features in Business Central, because while you can print using the…

    3 Comments

Others also viewed

Explore content categories