Multi-Factor Authentication

My project is using platform-6.6.4, and I have a requirement to implement multi-factor authentication. Basic login procedure must be as follows:

  1. User enters login and password as usual on the login page.
  2. Once that information is verified, the system generates a random token and sends it to the User. Another field/page (not sure what the best approach is) is displayed, allowing the User to enter the token.
  3. If the token is correct, proceed with session creation.

I’ve dug into the code and it appears that the custom logic needs to be added to the middle of LoginWorkerBean.login(). After a successful call to passwordEncryption.checkPassword(), I would need to perform the token generation and either navigate to another page and/or update the login page so the User can enter the token. Then I would need to verify the token and continue on with the login process.

I did a lot of research, but I’m not sure if this is actually the best approach… is it? If not, what is the best way to implement this functionality? I know that login functionality has been changed in a recent release, would it be easier to implement if I upgraded?

Assuming my analysis led me to the right approach, I’m not sure how to update the UI accordingly… any guidance would be greatly appreciated.

Hi,

You can implement something like this if you simply extend AppLoginWindow, take a look at this topic: Two-factor authentication - #3 от пользователя artamonov - CUBA.Platform

At the moment it is easier than before, just override AppLoginWindow#doLogin(Credentials) method with your own logic.

Hi Yuriy,
Thanks for the reply. I’m familiar with the topic discussing Google Authenticator two-factor authentication that you linked to, however that approach will not work for me. And since I’m on platform-6.6.4, it’s a bit more complicated than overriding AppLoginWindow#doLogin.

I was in a rush and needed to get this done before a security audit, so I coded a solution myself. I overrode DefaultApp#ConnectionStateChanged to generate a security code and store it in a session attribute. I also overrode DefaultApp#afterLoggedIn to check for that attribute and, if it exists, force a dialog where the User must enter the security code (similar to what it does when getChangePasswordAtNextLogon is true). I use a timer on that dialog to keep track of how long the page is open and, if the timeout interval is met, force logout so they will have to start the process all over again. It may not be the best approach, but it’s the best I could come up with in the allotted time.

I really got stuck on how to force the user back to the login screen upon timeout, so I ended up using the same functionality that’s used for the logout button (App#logout). However, it would be preferable to expire their session rather than log them out. It looks like you provided an answer to another topic of mine that may be relevant (Extend Session and Redirect to Login When Expired - #3 от пользователя artamonov - CUBA.Platform), so I’ll take a look at that and see if it helps.