Closed MrKementari closed 3 years ago
Seems to be working in the unit tests for DJango 3.1.3.
Are you sure the djangoadminrestrict middleware is installed correctly? What does your settings.py for your project look like?
On Sat, Nov 21, 2020 at 8:21 AM MrKementari notifications@github.com wrote:
Hello,
I'm facing some issue using django-adminrestrict, with Django 3.1.3, uwsgi 2.0.19.1 and nginx 1.16.1, all installed on a CentOS 7 server.
I've installed and configured everything, but it seems django-adminrestrict does not restrict anything at all :-)
I have only 2 IP adresses allowed to access my django admin page, but everybody seems to be able to access admin pages. Is there anything I'm doing wrong, or I forgot ?
Thanks by advance :-)
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/robromano/django-adminrestrict/issues/14, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVDPZVIGGTL4K2NUDJSX5LSQ7SIJANCNFSM4T536VUQ .
Hi,
this is my settings.py looks like :
"""
Django settings for LTU project.
Generated by 'django-admin startproject' using Django 3.0.3.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '****'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = [
'localhost',
]
# Application definition
INSTALLED_APPS = [
'realty.apps.RealtyConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'adminrestrict',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'adminrestrict.middleware.AdminPagesRestrictMiddleware',
]
ROOT_URLCONF = 'LTU.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'LTU.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'LTU_prd',
'USER': 'LTU_prd',
'PASSWORD': '****',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'fr-fr'
TIME_ZONE = 'Europe/Paris'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = 'static'
# Link to media
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
I did the following too :
python3 manage.py makemigrations adminrestrict; python3 manage.py migrate
But I had to add the --fake-init option to the migrate command, else I had some exceptions.
Looks okay as far as I can tell.
I suggest debugging the actual middleware code to determine if it's even being called (it should be) and if so, which condition is failing.
Add some print / logging statements into the process_request() method of the class shown below. You'll see that there are various conditions that must all be met. For example, it should be returning 1 or more AllowedIP objects from the query to the model, and then from there the comparisons of the actual IP to the allowed IPs should be checked.
Let me know if you figure it out. I'm sure from this code you'll see which condition isn't working.
class AdminPagesRestrictMiddleware(parent_class): """ A middleware that restricts login attempts to admin pages to restricted IP addresses only. Everyone else gets 403. """
def process_request(self, request): """ Check if the request is made form an allowed IP """
restricted_request_uri = request.path.startswith( reverse('admin:index') or "cms-toolbar-login" in request.build_absolute_uri() ) if restricted_request_uri and request.method == 'POST':
if AllowedIP.objects.count() > 0:
if AllowedIP.objects.filter(ip_address="*").count() == 0:
request_ip = get_ip_address_from_request(request)
if AllowedIP.objects.filter(ip_address=request_ip).count() == 0:
for regex_ip_range in AllowedIP.objects.filter(ip_address__endswith=""): if re.match(regex_ip_range.ip_address.replace("", ".*"), request_ip): return None return HttpResponseForbidden("Access to admin is denied.")
On Sat, Nov 21, 2020 at 1:50 PM MrKementari notifications@github.com wrote:
Hi,
this is my settings.py looks like :
""" Django settings for LTU project.
Generated by 'django-admin startproject' using Django 3.0.3.
For more information on this file, seehttps://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, seehttps://docs.djangoproject.com/en/3.0/ref/settings/ """
import os
Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))
Quick-start development settings - unsuitable for production
See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '****'
SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True ALLOWED_HOSTS = [ 'localhost', ]
Application definition
INSTALLED_APPS = [ 'realty.apps.RealtyConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'adminrestrict', ]
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'adminrestrict.middleware.AdminPagesRestrictMiddleware', ]
ROOT_URLCONF = 'LTU.urls'
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
WSGI_APPLICATION = 'LTU.wsgi.application'
Database
https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'LTU_prd', 'USER': 'LTU_prd', 'PASSWORD': '****', 'HOST': '127.0.0.1', 'PORT': '3306', } }
Password validation
https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ]
Internationalization
https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'fr-fr' TIME_ZONE = 'Europe/Paris' USE_I18N = True USE_L10N = True USE_TZ = True
Static files (CSS, JavaScript, Images)
https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/' STATIC_ROOT = 'static'
Link to media
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
I did the following too : python3 manage.py makemigrations adminrestrict; python3 manage.py migrate
But I had to add the --fake-init option to the migrate command, else I had some exceptions.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/robromano/django-adminrestrict/issues/14#issuecomment-731641996, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVDPZUEDMJ3GG5E56G3IOLSRAYY3ANCNFSM4T536VUQ .
Hi,
I've added some logging in your module, and I have figured out what happens :
def process_request(self, request):
"""
Check if the request is made form an allowed IP
"""
# Section adjusted to restrict login to ?edit
# (sing cms-toolbar-login)into DjangoCMS login.
restricted_request_uri = request.path.startswith(
reverse('admin:index') or "cms-toolbar-login" in request.build_absolute_uri()
)
logging.debug("Restricted request uri : {}".format(restricted_request_uri))
logging.debug("Request method : {}".format(request.method)
)
Here is what I get when I try to access admin pages :
DEBUG:root:Restricted request uri : True
DEBUG:root:Request method : GET
But in the module, all access restrictions applied to POST requests, as its shown below :
if restricted_request_uri and request.method == 'POST':
# AllowedIP table emty means access is always granted
if AllowedIP.objects.count() > 0:
# If there are wildcard IPs access is always granted
if AllowedIP.objects.filter(ip_address="*").count() == 0:
...
So if I change POST to GET, it works. But I don't really know if it's a proper functioning ?
When the /admin pages are first accessed by a user, the user must login to be authenticated. To authenticate, a POST of the login credentials is sent. This is what is blocked by adminrestrict.
Maybe what happened is you were already logged in -- before you enabled the adminrestrict package or IP addresses. Since you're already logged in, you are continuing to access the pages with old credentials. Try logging out and logging in. I believe once you are logged out the restrictions are going to work.
On Mon, Nov 23, 2020 at 12:50 AM MrKementari notifications@github.com wrote:
Hi,
I've added some logging in your module, and I have figured out what happens :
def process_request(self, request): """ Check if the request is made form an allowed IP """
Section adjusted to restrict login to ?edit
# (sing cms-toolbar-login)into DjangoCMS login. restricted_request_uri = request.path.startswith( reverse('admin:index') or "cms-toolbar-login" in request.build_absolute_uri() ) logging.debug("Restricted request uri : {}".format(restricted_request_uri)) logging.debug("Request method : {}".format(request.method)
)
Here is what I get when I try to access admin pages :
DEBUG:root:Restricted request uri : True DEBUG:root:Request method : GET
But in the module, all access restrictions applied to POST requests, as its shown below :
if restricted_request_uri and request.method == 'POST':
# AllowedIP table emty means access is always granted if AllowedIP.objects.count() > 0: # If there are wildcard IPs access is always granted if AllowedIP.objects.filter(ip_address="*").count() == 0: ...
So if I change POST to GET, it works. But I don't really know if it's a proper functioning ?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/robromano/django-adminrestrict/issues/14#issuecomment-732018299, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVDPZQ6RDOW2OGNDHRGQNLSRIO5TANCNFSM4T536VUQ .
Hmm okay I think I probably misunderstood the proper functioning of your plugin, initially I wanted to deny access even to the admin login console. As I understand of your answer, with POST method, admin login would have been displayed but only allowed IP addresses would have be able to authenticate right ?
That’s right. Only the allowed IP addresses would be able to login so effectively the entire console would always be blocked (generating http status 403), no matter what credentials are provided.
I can see both versions being useful - one that effectively hides the admin console altogether and one that shows the console but won’t accept any credentials from unknown IPs.
I think we can enhance the plug-in to support both, maybe as simply as what you found by returning 403 for GET as well.
On Tue, Nov 24, 2020 at 1:43 AM MrKementari notifications@github.com wrote:
Hmm okay I think I probably misunderstood the proper functioning of your plugin, initially I wanted to deny access even to the admin login console. As I understand of your answer, admin login would have been displayed but only allowed IP addresses would have be able to connect right ?
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/robromano/django-adminrestrict/issues/14#issuecomment-732779775, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVDPZQQELZN5KVIMCISAX3SRN54VANCNFSM4T536VUQ .
I’ve made some enhancements to adminrestrict to support blocking all accesses - GET included via special settings in settings.py you can set:
ADMINRESTRICT_BLOCK_GET=True will block all GET requests to admin urls. By default, adminrestrict only blocks the POST method to block logins only, which is usually sufficient, because GET will redirect to the login page anyway.
I haven’t pushed the new version to PyPi yet.
On Tue, Nov 24, 2020 at 8:46 PM Robert C. Romano rromano@gmail.com wrote:
That’s right. Only the allowed IP addresses would be able to login so effectively the entire console would always be blocked (generating http status 403), no matter what credentials are provided.
I can see both versions being useful - one that effectively hides the admin console altogether and one that shows the console but won’t accept any credentials from unknown IPs.
I think we can enhance the plug-in to support both, maybe as simply as what you found by returning 403 for GET as well.
On Tue, Nov 24, 2020 at 1:43 AM MrKementari notifications@github.com wrote:
Hmm okay I think I probably misunderstood the proper functioning of your plugin, initially I wanted to deny access even to the admin login console. As I understand of your answer, admin login would have been displayed but only allowed IP addresses would have be able to connect right ?
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/robromano/django-adminrestrict/issues/14#issuecomment-732779775, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVDPZQQELZN5KVIMCISAX3SRN54VANCNFSM4T536VUQ .
Thanks 👍
It seems ok for me, I think I can close the issue ?
Thanks for your work !
Hello,
I'm facing some issue using django-adminrestrict, with Django 3.1.3, uwsgi 2.0.19.1 and nginx 1.16.1, all installed on a CentOS 7 server.
I've installed and configured everything, but it seems django-adminrestrict does not restrict anything at all :-)
I have only 2 IP adresses allowed to access my django admin page, but everybody seems to be able to access admin pages. Is there anything I'm doing wrong, or I forgot ?
Thanks by advance :-)