diff --git a/hypha/apply/users/middleware.py b/hypha/apply/users/middleware.py
index 4ebdf2d0e55453a10ffbe6b5069c04ec03f1d53a..53ae4fc4f3bc1363d4a7d528459805271e69e43d 100644
--- a/hypha/apply/users/middleware.py
+++ b/hypha/apply/users/middleware.py
@@ -1,8 +1,16 @@
+from django.conf import settings
+from django.shortcuts import redirect
 from social_core.exceptions import AuthForbidden
 from social_django.middleware import (
     SocialAuthExceptionMiddleware as _SocialAuthExceptionMiddleware,
 )
 
+ALLOWED_SUBPATH_FOR_UNVERIFIED_USERS = [
+    'login/',
+    'logout/',
+    'account/',
+]
+
 
 class SocialAuthExceptionMiddleware(_SocialAuthExceptionMiddleware):
     """
@@ -13,3 +21,36 @@ class SocialAuthExceptionMiddleware(_SocialAuthExceptionMiddleware):
             return 'Your credentials are not recognised.'
 
         super().get_message(request, exception)
+
+
+class TwoFactorAuthenticationMiddleware:
+    """
+    Middleware to enforce 2FA activation for unverified users
+
+    To activate this middleware set env variable ENFORCE_TWO_FACTOR as True.
+
+    This will redirect all request from unverified users to enable 2FA first.
+    Except the request made on the url paths listed in ALLOWED_SUBPATH_FOR_UNVERIFIED_USERS.
+    """
+    def __init__(self, get_response):
+        self.get_response = get_response
+
+    def is_path_allowed(self, path):
+
+        for sub_path in ALLOWED_SUBPATH_FOR_UNVERIFIED_USERS:
+            if sub_path in path:
+                return True
+        return False
+
+    def __call__(self, request):
+        # code to execute before the view
+        user = request.user
+        if settings.ENFORCE_TWO_FACTOR:
+            if user.is_authenticated and not user.is_verified() and not user.social_auth.exists():
+                if not self.is_path_allowed(request.path):
+                    return redirect('/account/two_factor/required/')
+
+        response = self.get_response(request)
+
+        # code to execute after view
+        return response
diff --git a/hypha/apply/users/templates/two_factor/core/two_factor_required.html b/hypha/apply/users/templates/two_factor/core/two_factor_required.html
new file mode 100644
index 0000000000000000000000000000000000000000..64ed802ae57c9688282b1cf70b24b9669efe7264
--- /dev/null
+++ b/hypha/apply/users/templates/two_factor/core/two_factor_required.html
@@ -0,0 +1,22 @@
+<!--Custom template to enforce 2FA and Copied from two_factor/core/otp_required.html-->
+
+{% extends "two_factor/_base_focus.html" %}
+{% load i18n %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Permission Denied" %}{% endblock %}</h1>
+
+  <p>{% blocktrans trimmed %}The page you requested, enforces users to verify using
+    two-factor authentication for security reasons. You need to enable these
+    security features in order to access this page. Without enabling these security features,
+      You can only access the account(Profile section) or can logout from the system.{% endblocktrans %}</p>
+
+  <p>{% blocktrans trimmed %}Two-factor authentication is not enabled for your
+    account. Enable two-factor authentication for enhanced account
+    security.{% endblocktrans %}</p>
+
+  <p>
+    <a href="{% url 'two_factor:setup' %}" class="btn btn-primary">
+    {% trans "Enable Two-Factor Authentication" %}</a>
+  </p>
+{% endblock %}
diff --git a/hypha/apply/users/tests/test_middleware.py b/hypha/apply/users/tests/test_middleware.py
new file mode 100644
index 0000000000000000000000000000000000000000..6800bb67ba2247e3dad6b7b57787fe25fffa9989
--- /dev/null
+++ b/hypha/apply/users/tests/test_middleware.py
@@ -0,0 +1,41 @@
+from django.conf import settings
+from django.test import TestCase, override_settings
+from django.urls import reverse
+
+from hypha.apply.users.tests.factories import UserFactory
+
+from ..middleware import ALLOWED_SUBPATH_FOR_UNVERIFIED_USERS
+
+
+@override_settings(ROOT_URLCONF='hypha.apply.urls', ENFORCE_TWO_FACTOR=True)
+class TestTwoFactorAuthenticationMiddleware(TestCase):
+    def enable_otp(self, user):
+        return user.totpdevice_set.create(name='default')
+
+    def test_unverified_user_redirect(self):
+        user = UserFactory()
+        self.client.force_login(user)
+
+        response = self.client.get(settings.LOGIN_REDIRECT_URL, follow=True)
+        self.assertRedirects(response, reverse('users:two_factor_required'), status_code=301)
+
+        response = self.client.get(reverse('funds:submissions:list'), follow=True)
+        self.assertRedirects(response, reverse('users:two_factor_required'), status_code=301)
+
+    def test_verified_user_redirect(self):
+        user = UserFactory()
+        self.client.force_login(user)
+        self.enable_otp(user=user)
+        response = self.client.get(settings.LOGIN_REDIRECT_URL, follow=True)
+        self.assertEqual(response.status_code, 200)
+
+        response = self.client.get(reverse('funds:submissions:list'), follow=True)
+        self.assertEqual(response.status_code, 200)
+
+    def test_unverified_user_can_access_allowed_urls(self):
+        user = UserFactory()
+        self.client.force_login(user)
+
+        for path in ALLOWED_SUBPATH_FOR_UNVERIFIED_USERS:
+            response = self.client.get(path, follow=True)
+            self.assertEqual(response.status_code, 200)
diff --git a/hypha/apply/users/urls.py b/hypha/apply/users/urls.py
index eaea2ed6784a6c2e84ee5de7e3e11450539fcfe4..94bc9bb2ff835b4cdd36f589eafe7aeab3d1983b 100644
--- a/hypha/apply/users/urls.py
+++ b/hypha/apply/users/urls.py
@@ -10,6 +10,7 @@ from .views import (
     LoginView,
     TWOFABackupTokensPasswordView,
     TWOFADisableView,
+    TWOFARequiredMessageView,
     become,
     create_password,
     oauth,
@@ -83,6 +84,8 @@ urlpatterns = [
             ActivationView.as_view(),
             name='activate'
         ),
+        # Two factor redirect
+        path('two_factor/required/', TWOFARequiredMessageView.as_view(), name='two_factor_required'),
         path('two_factor/backup_tokens/password/', TWOFABackupTokensPasswordView.as_view(), name='backup_tokens_password'),
         path('two_factor/disable/', TWOFADisableView.as_view(), name='disable'),
         path('confirmation/done/', EmailChangeDoneView.as_view(), name="confirm_link_sent"),
diff --git a/hypha/apply/users/views.py b/hypha/apply/users/views.py
index b5266400ff86d7c0d5244cc89ac27b047a18bd10..6bf3241b353e8be114120cc3ad00fb8d7cccfa76 100644
--- a/hypha/apply/users/views.py
+++ b/hypha/apply/users/views.py
@@ -304,3 +304,7 @@ class TWOFADisableView(TwoFactorDisableView):
         kwargs = super().get_form_kwargs()
         kwargs['user'] = self.request.user
         return kwargs
+
+
+class TWOFARequiredMessageView(TemplateView):
+    template_name = 'two_factor/core/two_factor_required.html'
diff --git a/hypha/settings/base.py b/hypha/settings/base.py
index d0379bd6a8321fd4be66fea9973cf87ff64d4839..8eb1f01fade095472701ffc1c85bd721e15fb794 100644
--- a/hypha/settings/base.py
+++ b/hypha/settings/base.py
@@ -146,6 +146,7 @@ MIDDLEWARE = [
 
     'hijack.middleware.HijackUserMiddleware',
 
+    'hypha.apply.users.middleware.TwoFactorAuthenticationMiddleware',
     'hypha.apply.users.middleware.SocialAuthExceptionMiddleware',
 
     'wagtail.contrib.redirects.middleware.RedirectMiddleware',
@@ -361,6 +362,9 @@ WAGTAIL_PASSWORD_MANAGEMENT_ENABLED = False
 WAGTAILUSERS_PASSWORD_ENABLED = False
 WAGTAILUSERS_PASSWORD_REQUIRED = False
 
+# Enforce Two factor setting
+ENFORCE_TWO_FACTOR = env.bool('ENFORCE_TWO_FACTOR', False)
+
 LOGIN_URL = 'users_public:login'
 LOGIN_REDIRECT_URL = 'dashboard:dashboard'