I wanted to do basic authentication before the login screen on the Django admin page. But I didn't want to go to other pages. I don't know much about Django and python, but I think I've done it for the time being, so I'll expose it. I don't think it's the best solution, so please let me know if there is a better way.
python: 3.5.2 Django==1.11.4
It's hard to say that the result of trial and error for about two days is super simple.
yourproject/my_admin_site.py
from django.http import HttpResponse
from django.views.decorators.cache import never_cache
from django.contrib.admin.sites import site, AdminSite
import base64
class MyAdminSite(AdminSite):
def __init__(self, name='admin'):
super().__init__()
def get_urls(self):
self._registry = site._registry
return super().get_urls()
@never_cache
def login(self, request, extra_context=None):
if not self._basicAuth(request):
return self._http401()
return super().login(request, extra_context)
def _basicAuth(self, request):
if 'HTTP_AUTHORIZATION' not in request.META:
return False
(authscheme, base64_idpass) = request.META['HTTP_AUTHORIZATION'].split(' ', 1)
if authscheme.lower() != 'basic':
return _http401()
idpass = base64.decodestring(base64_idpass.strip().encode('ascii')).decode('ascii')
(id_, password) = idpass.split(':', 1)
if id_ == "foo" and password == "bar":
return True
else:
return False
def _http401(self):
response = HttpResponse("Unauthorized", status=401)
response['WWW-Authenticate'] = 'Basic realm="basic auth test"'
return response
my_site = MyAdminSite()
yourproject/urls.py
from django.conf.urls import url, include
from yourproject import my_admin_site
urlpatterns = [
#url(r'^admin/', admin.site.urls),
url(r'^admin/', my_admin_site.my_site.urls)
]
It is like this.
yourproject/my_admin_site.py
def get_urls(self):
self._registry = site._registry
return super().get_urls()
Basic authentication can be done without this part, but without this, a sad screen appears saying that no operation can be performed when entering admin. The list of models that can be operated is registered from the outside in _register of django.contrib.admin.sites.site, so it seems that you can not pull that information if you just inherit the model? So I solved it by copying django.contrib.admin.sites.site. \ _Register to my own class self. \ _ Register. I feel like doing it. I don't like accessing the implicit private method, but it worked. Perhaps. There is no inconvenience for now.
I think it's good and bad that there is no clear difference between python, public and private.
Reference https://bitstar.jp/blog/basic%E8%AA%8D%E8%A8%BC
Recommended Posts