I’m using 2FA for logins, but I need to have it enabled only when accessing the site from non-trusted IPs
I already had been doing this for CAPTCHA using the following code in globals:
//Disable reCaptcha for locally hosted servers
$localIPs="xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxy, xxx.xxx.xxx.xxz";
$externalIPs="xxx.xxx.xxx.abc, xxx.xxx.xxx.def";
if (strpos($localIPs,$_SERVER['SERVER_ADDR'])>0 || strpos($externalIPs,$_SERVER['REMOTE_ADDR'])>0) { // check if allowed local IP without recaptcha
$CaptchaClass = "CaptchaBase"; /// Without Recaptcha
}
2FA is part of the AUTH_CONFIG section, and the syntax is different.
How can I oveeride only these in Globals with false values?
You may generate another version of your project without 2FA, then compare the two version and find out the differences, and see if you can make the changes by server events.
yes that’s what I was thinking. I may generate two config files, one with and one without 2FA, rename them, then php include one or the other based on IP address.
I’ve had this working for a while now… this was the code placed in globals:
/Bypass 2FA for trusted networks
//get external IPs
// Sanitize user input (user's IP address)
$conn = Conn();
$userIp = $_SERVER['REMOTE_ADDR'];
// Sanitize user input (user's IP address)
$userIp = $conn->quote($userIp);
// Construct the SQL query
$query = "SELECT IP FROM ClassAct_Trusted_IPs WHERE IP = $userIp";
// Execute the query
$result = $conn->executeQuery($query);
// Check the result and configure 2FA accordingly
$row = $result->fetchAssociative();
if (!empty($row)) {
Config("USE_TWO_FACTOR_AUTHENTICATION", false);
Config("FORCE_TWO_FACTOR_AUTHENTICATION", false);
session_start();
$_SESSION['redirme'] = 'trust'.time();
} else {
Config("USE_TWO_FACTOR_AUTHENTICATION", true);
Config("FORCE_TWO_FACTOR_AUTHENTICATION", true);
}
//End 2FA bypass
I don’t like the fact that it’s in globals (doesn’t seem right) and it’s not within a function, but also now I need to be able to bypass 2FA for certain users.
My site has a few demo accounts which mustn’t request a security code at login.
So I’m trying to figure out way around that.
I have tried a few things and got it accidentally working only once.
Essentially, I’d need to throw the username into a session on first click of the Login button, and there would have to be some code in page_Load server event for the logon page.
So I deally I’m trying to adapt the code above to include username session checking.I there a session already set on submit of the login form which I could use?
Or is there a simpler way to achieve what I’m looking for?
Hi there - I’m working on this exact same thing. Did you figure out a way to dynamically enable and disable 2FA? I’d like to have it disabled on the local network, and enabled for people on outside ip addresses.Anybody know - would it be possible to have conditional 2FA with SMS?What I’d like to do is this - if person is on the local network, no 2FA. If outside the local network require 2FA.Anybody know how to do this? Thanks!
However, the system freezes, and I have to refresh the screen. Session Start, or even a meta redirect doesn’t work. How can I make it proceed after setting the two Config lines so the user doesn’t have to refresh the screen?I think I’m close. Thanks.
You may use Page_Redirecting server event to check if the user is authenticated and set $this->IsModal = true; to simulate JSON response originally for 2FA.
sorry for delay.
note I replaced my local Ip addresses with xxx.this is returning an error if login or password is wrong so I will continue to tweak, but this is the basic idea:in login page, Page_Redirecting event:
I know its been a while, but just wanted to say that I found a very solid and simple method for this. Works in 2023, not tested on later versions yet.
First make sure your site has 2FA turned on.
In Global Code:
// 3. Bypass 2FA for trusted networks
$userIp = $_SERVER['REMOTE_ADDR'];
$userIp = AdjustSql($userIp);
//make sure you have a table named Trusted_IPs !!
$query = "SELECT IP FROM Trusted_IPs WHERE IP = '$userIp'";
$result = ExecuteQuery($query);
$row = $result->fetchAssociative();
if (!empty($row)) {
Config("USE_TWO_FACTOR_AUTHENTICATION", false);
Config("FORCE_TWO_FACTOR_AUTHENTICATION", false);
$_SESSION['redirme'] = 'trust' . time();
} else {
Config("USE_TWO_FACTOR_AUTHENTICATION", true);
Config("FORCE_TWO_FACTOR_AUTHENTICATION", true);
}
In events > Other > Login Page > User_Loggedin:
// If we are on a trusted network, ensure we clear the 2FA flag and force a redirect
if (isset($_SESSION['redirme'])) {
// Check for AJAX header directly to avoid Config index errors
$isAjax = (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if ($isAjax) {
// Clear any previous output buffers to ensure clean JSON
while (ob_get_level()) {
ob_end_clean();
}
// Return JSON redirect for the login page JavaScript
header('Content-Type: application/json');
echo json_encode(["url" => GetUrl("Home")]);
exit();
} else {
// Standard redirect using the class method
$this->Terminate('Home');
}
}