From 3ad316cdca1a2d0989a05e7ce35566fc530706e4 Mon Sep 17 00:00:00 2001 From: juanifioren Date: Wed, 4 Mar 2015 16:24:41 -0300 Subject: [PATCH] Add Provider Configuration Information endpoint. --- oidc_provider/lib/endpoints/authorize.py | 4 ++- oidc_provider/lib/endpoints/discovery.py | 31 ++++++++++++++++++++++++ oidc_provider/lib/endpoints/token.py | 3 ++- oidc_provider/lib/endpoints/userinfo.py | 4 ++- oidc_provider/lib/utils/common.py | 16 ++++++++++++ oidc_provider/urls.py | 2 ++ oidc_provider/views.py | 15 +++++++++++- 7 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 oidc_provider/lib/endpoints/discovery.py create mode 100644 oidc_provider/lib/utils/common.py diff --git a/oidc_provider/lib/endpoints/authorize.py b/oidc_provider/lib/endpoints/authorize.py index b6ca2fe..362dd56 100644 --- a/oidc_provider/lib/endpoints/authorize.py +++ b/oidc_provider/lib/endpoints/authorize.py @@ -1,11 +1,13 @@ from datetime import timedelta +import uuid + from django.utils import timezone + from oidc_provider.lib.errors import * from oidc_provider.lib.utils.params import * from oidc_provider.lib.utils.token import * from oidc_provider.models import * from oidc_provider import settings -import uuid class AuthorizeEndpoint(object): diff --git a/oidc_provider/lib/endpoints/discovery.py b/oidc_provider/lib/endpoints/discovery.py new file mode 100644 index 0000000..945695f --- /dev/null +++ b/oidc_provider/lib/endpoints/discovery.py @@ -0,0 +1,31 @@ +from django.core.urlresolvers import reverse + +from oidc_provider import settings +from oidc_provider.lib.utils.common import get_issuer + + +class ProviderInfoEndpoint(object): + + @classmethod + def create_response_dic(cls): + dic = {} + + dic['issuer'] = get_issuer() + + SITE_URL = settings.get('SITE_URL') + + dic['authorization_endpoint'] = SITE_URL + reverse('oidc_provider:authorize') + dic['token_endpoint'] = SITE_URL + reverse('oidc_provider:token') + dic['userinfo_endpoint'] = SITE_URL + reverse('oidc_provider:userinfo') + + from oidc_provider.models import Client + types_supported = [x[0] for x in Client.RESPONSE_TYPE_CHOICES] + dic['response_types_supported'] = types_supported + + # TODO: + #dic['jwks_uri'] = None + + # See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes + dic['subject_types_supported'] = ['public'] + + return dic \ No newline at end of file diff --git a/oidc_provider/lib/endpoints/token.py b/oidc_provider/lib/endpoints/token.py index d2c3582..47437ae 100644 --- a/oidc_provider/lib/endpoints/token.py +++ b/oidc_provider/lib/endpoints/token.py @@ -3,6 +3,7 @@ import urllib from django.http import JsonResponse from oidc_provider.lib.errors import * +from oidc_provider.lib.utils.common import get_issuer from oidc_provider.lib.utils.params import * from oidc_provider.lib.utils.token import * from oidc_provider.models import * @@ -61,7 +62,7 @@ class TokenEndpoint(object): user=self.code.user) id_token_dic = create_id_token( - iss=settings.get('SITE_URL'), + iss=get_issuer(), sub=sub, aud=self.client.client_id, auth_time=self.code.user.last_login) diff --git a/oidc_provider/lib/endpoints/userinfo.py b/oidc_provider/lib/endpoints/userinfo.py index 163dfd5..3a7a48c 100644 --- a/oidc_provider/lib/endpoints/userinfo.py +++ b/oidc_provider/lib/endpoints/userinfo.py @@ -1,11 +1,13 @@ +import re + from django.http import HttpResponse from django.http import JsonResponse + from oidc_provider.lib.errors import * from oidc_provider.lib.claims import * from oidc_provider.lib.utils.params import * from oidc_provider.models import * from oidc_provider import settings -import re class UserInfoEndpoint(object): diff --git a/oidc_provider/lib/utils/common.py b/oidc_provider/lib/utils/common.py new file mode 100644 index 0000000..7f0a626 --- /dev/null +++ b/oidc_provider/lib/utils/common.py @@ -0,0 +1,16 @@ +from django.core.urlresolvers import reverse + +from oidc_provider import settings + + +def get_issuer(): + """ + Construct the issuer full url. Basically is the site url with some path + appended. + """ + site_url = settings.get('SITE_URL') + path = reverse('oidc_provider:provider_info') \ + .split('/.well-known/openid-configuration/')[0] + issuer = site_url + path + + return issuer diff --git a/oidc_provider/urls.py b/oidc_provider/urls.py index 54c4f62..1667b48 100644 --- a/oidc_provider/urls.py +++ b/oidc_provider/urls.py @@ -9,4 +9,6 @@ urlpatterns = patterns('', url(r'^token/$', csrf_exempt(TokenView.as_view()), name='token'), url(r'^userinfo/$', csrf_exempt(userinfo), name='userinfo'), + url(r'^\.well-known/openid-configuration/$', ProviderInfoView.as_view(), name='provider_info'), + ) \ No newline at end of file diff --git a/oidc_provider/views.py b/oidc_provider/views.py index 7b4a693..928b838 100644 --- a/oidc_provider/views.py +++ b/oidc_provider/views.py @@ -4,10 +4,12 @@ from django.shortcuts import render from django.template.loader import render_to_string from django.views.decorators.http import require_http_methods from django.views.generic import View -from oidc_provider.lib.errors import * + from oidc_provider.lib.endpoints.authorize import * +from oidc_provider.lib.endpoints.discovery import * from oidc_provider.lib.endpoints.token import * from oidc_provider.lib.endpoints.userinfo import * +from oidc_provider.lib.errors import * class AuthorizeView(View): @@ -75,6 +77,7 @@ class AuthorizeView(View): return HttpResponseRedirect(uri) + class TokenView(View): def post(self, request, *args, **kwargs): @@ -91,6 +94,7 @@ class TokenView(View): except (TokenError) as error: return TokenEndpoint.response(error.create_dict(), status=400) + @require_http_methods(['GET', 'POST']) def userinfo(request): @@ -108,3 +112,12 @@ def userinfo(request): error.code, error.description, error.status) + + +class ProviderInfoView(View): + + def get(self, request, *args, **kwargs): + + dic = ProviderInfoEndpoint.create_response_dic() + + return JsonResponse(dic) \ No newline at end of file