Django request for CAC (common access card)

316 Views Asked by At

I am currently running my Django application on an Apache v2.4.5.2 server. When the user hits initial page (i.e. www.djangoApp.com) they are prompted to insert their CAC and PIN. Once complete, the PIN entry pop-up goes away and the user is directed to the landing page. The issue I'm having is figuring out how to identify the user based on the HTTP response received from the external source (GCDS). In the server logs, I can see the request information, but I am unsure how to view that request in Django views. I tried to comment out all middleware so that the request would make it through, but that doesn't work. Does Apache block certain HTTP Requests? Is there somewhere I need to allow external requests? The only request I'm getting is:

{'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PROTOCOL': 'HTTP/1.1', 'REQUEST_METHOD': 'GET', 'QUERY_STRING': '', 'REQUEST_URI': '/', 'SCRIPT_NAME': '', 'PATH_INFO': '/', 'PATH_TRANSLATED': '\DjangoWebProject1\\wsgi.py\\', 'HTTP_HOST': 'glen', 'HTTP_CACHE_CONTROL': 'max-age=0', 'HTTP_SEC_CH_UA': '" Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"', 'HTTP_SEC_CH_UA_MOBILE': '?0', 'HTTP_SEC_CH_UA_PLATFORM': '"Windows"', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'HTTP_SEC_FETCH_SITE': 'none', 'HTTP_SEC_FETCH_MODE': 'navigate', 'HTTP_SEC_FETCH_USER': '?1', 'HTTP_SEC_FETCH_DEST': 'document', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.9', 'HTTP_COOKIE': 'csrftoken=Nd3ggEPk0vqYJwZKOVZZoZtUqZWXs155Y6V1q', 'HTTP_X_FORWARDED_FOR': '128.202.106.24', 'HTTP_X_FORWARDED_HOST': 'glen', 'HTTP_X_FORWARDED_SERVER': 'glen', 'HTTP_CONNECTION': 'Keep-Alive', 'SystemRoot': 'C:\\Windows', 'COMSPEC': 'C:\\Windows\\system32\\cmd.exe', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'WINDIR': 'C:\\Windows', 'SERVER_SIGNATURE': '', 'SERVER_SOFTWARE': 'Apache/2.4.52 (Win64) OpenSSL/1.1.1m mod_wsgi/4.9.0 Python/3.9', 'SERVER_NAME': 'glen', 'SERVER_ADDR': 'fe80::ed01:effd:2360:544a', 'SERVER_PORT': '81', 'REMOTE_ADDR': 'fe80::ed01:effd::544a', 'DOCUMENT_ROOT': 'webdart/DjangoWebProject1/webdart/templates/webdart', 'REQUEST_SCHEME': 'http', 'CONTEXT_PREFIX': '', 'CONTEXT_DOCUMENT_ROOT': 'webdart/DjangoWebProject1/webdart/templates/webdart', 'SERVER_ADMIN': '[email protected]', 'SCRIPT_FILENAME': 'webdart/DjangoWebProject1/DjangoWebProject1/wsgi.py', 'REMOTE_PORT': '6307', 'mod_wsgi.script_name': '', 'mod_wsgi.path_info': '/', 'mod_wsgi.process_group': '', 'mod_wsgi.application_group': 'GLEN:81|', 'mod_wsgi.callable_object': 'application', 'mod_wsgi.request_handler': 'wsgi-script', 'mod_wsgi.handler_script': '', 'mod_wsgi.script_reloading': '1', 'mod_wsgi.enable_sendfile': '0', 'mod_wsgi.ignore_activity': '0', 'mod_wsgi.request_start': '17490697', 'mod_wsgi.request_id': 'iT3r3Lez7vM', 'mod_wsgi.connection_id': 'iT3r3Lez7vM', 'mod_wsgi.script_start': '1069256341', 'wsgi.version': (1, 0), 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.errors': <_io.TextIOWrapper name='<wsgi.errors>' encoding='utf-8'>, 'wsgi.input': <mod_wsgi.Input object at 0x00000286F4E619D0>, 'wsgi.input_terminated': True, 'wsgi.file_wrapper': <class 'mod_wsgi.FileWrapper'>, 'apache.version': (2, 4, 52), 'mod_wsgi.version': (4, 9, 0), 'mod_wsgi.total_requests': 0, 'mod_wsgi.thread_id': 1, 'mod_wsgi.thread_requests': 0, 'CSRF_COOKIE': 'N2kUXzZUXThFW1w52r4ZKOVZZoZtUqZWXs155Y6V1q'}

My settings.py looks like this:

Django settings for DjangoWebProject1 project.

Based on 'django-admin startproject' using Django 2.1.2.

For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""

import os
import posixpath

# 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/2.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'd050e2cb-bfba-4ff7-adc1-9c1c8e8d952b'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application references
# https://docs.djangoproject.com/en/2.1/ref/settings/#std:setting-INSTALLED_APPS
INSTALLED_APPS = [
    'app',
    # Add your apps here to enable them
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'webdart.apps.WebdartConfig',
    'DjangoWebProject1',
    'django_filters',
    'vertical_multi_columns',
    'el_pagination',


]

# Middleware framework
# https://docs.djangoproject.com/en/2.1/topics/http/middleware/
MIDDLEWARE = [
    #'django.middleware.authenticate.printHeader',
    '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',
    
]
X_FRAME_OPTIONS = 'SAMEORIGIN';

ROOT_URLCONF = 'DjangoWebProject1.urls'

# Template configuration
# https://docs.djangoproject.com/en/2.1/topics/templates/
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'), ],
        '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',
                'django.template.context_processors.csrf',
                'django.template.context_processors.request', ## For EL-pagination
                'webdart.context_processors.add_doc_types_to_context',
                'webdart.context_processors.add_dynamic_stations_to_context',
            ],
            'libraries':{
                'webdart_extras':'webdart.templateTags.webdart_extras',
            }
        },
    },
]

WSGI_APPLICATION = 'DjangoWebProject1.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'ORCL',
        'USER': 'wd',
        'PASSWORD': 'password1',
        'HOST':'127.0.0.1',
        'PORT': '1521',
    }
}

# Password validation
# https://docs.djangoproject.com/en/2.1/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/2.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = posixpath.join(*(BASE_DIR.split(os.path.sep) + ['static']))
print("00011111111111111111111000000000")
print(STATIC_ROOT)

I've tried building my own middleware, commenting out all middleware... I'm stuck. How can I view the GCDS request containing the CAC information? Does Apache block certain HTTP Requests? Is there somewhere I need to allow external requests?

Here is the landing page from views.py:

def landing(request):
    test = request.META
    print(test)
    dodNum = "101010101"
    people = Person.objects.all()
    for person in people:
        if dodNum in person.authentication_name:
       
            return render(request, 'webdart/landing.html', {'person': person})
            break
    return render(request, 'webdart/accountRequest.html')

Again, when I am printing the "test" variable, all I am seeing are requests for the landing page/accountRequest page. No authentication info in the request

1

There are 1 best solutions below

1
On

The issue has to do with naming headers on the Apache side. Django drops all headers that are named with an underscore ("_"). However, if you use a dash ("-"), django will accept the header and convert the dash to an underscore.

We changed this in the httpd-ssl.conf file:

RequestHeader set REMOTE_USER "%{SSL_CLIENT_S_DN_CN}s"

to:

RequestHeader set REMOTE-USER "%{SSL_CLIENT_S_DN_CN}s"

Now in our views.py we can call request.META and get all authentication info. Even with the middleware, the request makes it though with all data.