example fix for userinfo CORS preflight request

Example for
https://github.com/juanifioren/django-oidc-provider/issues/249. If this
approach seems acceptable I can add/update tests.
This commit is contained in:
Andy Clayton 2018-06-19 11:09:45 -05:00
parent dfcc3de01c
commit 0adb95d25f
2 changed files with 40 additions and 7 deletions

View file

@ -2,6 +2,7 @@ from hashlib import sha224
import django
from django.http import HttpResponse
from django.utils.cache import patch_vary_headers
from oidc_provider import settings
@ -160,3 +161,26 @@ def run_processing_hook(subject, hook_settings_name, **kwargs):
subject = hook(subject, **kwargs)
return subject
def cors_allow_any(request, response):
"""
Add headers to permit CORS requests from any origin, with or without credentials,
with any headers.
"""
origin = request.META.get('HTTP_ORIGIN')
if not origin:
return response
# From the CORS spec: The string "*" cannot be used for a resource that supports credentials.
response['Access-Control-Allow-Origin'] = origin
patch_vary_headers(response, ['Origin'])
response['Access-Control-Allow-Credentials'] = 'true'
if request.method == 'OPTIONS':
if 'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' in request.META:
response['Access-Control-Allow-Headers'] \
= request.META['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
response['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
return response

View file

@ -19,7 +19,7 @@ try:
except ImportError:
from django.core.urlresolvers import reverse
from django.contrib.auth import logout as django_user_logout
from django.http import JsonResponse
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils.decorators import method_decorator
@ -43,6 +43,7 @@ from oidc_provider.lib.utils.common import (
redirect,
get_site_url,
get_issuer,
cors_allow_any,
)
from oidc_provider.lib.utils.oauth2 import protected_resource_view
from oidc_provider.lib.utils.token import client_id_from_id_token
@ -231,7 +232,7 @@ class TokenView(View):
return TokenEndpoint.response(error.create_dict(), status=403)
@require_http_methods(['GET', 'POST'])
@require_http_methods(['GET', 'POST', 'OPTIONS'])
@protected_resource_view(['openid'])
def userinfo(request, *args, **kwargs):
"""
@ -240,6 +241,16 @@ def userinfo(request, *args, **kwargs):
Return a dictionary.
"""
def set_headers(response):
response['Cache-Control'] = 'no-store'
response['Pragma'] = 'no-cache'
cors_allow_any(request, response)
return response
if request.method == 'OPTIONS':
return set_headers(HttpResponse())
token = kwargs['token']
dic = {
@ -253,12 +264,10 @@ def userinfo(request, *args, **kwargs):
extra_claims = settings.get('OIDC_EXTRA_SCOPE_CLAIMS', import_str=True)(token)
dic.update(extra_claims.create_response_dic())
response = JsonResponse(dic, status=200)
response['Access-Control-Allow-Origin'] = '*'
response['Cache-Control'] = 'no-store'
response['Pragma'] = 'no-cache'
success_response = JsonResponse(dic, status=200)
set_headers(success_response)
return response
return success_response
class ProviderInfoView(View):