diff --git a/cas_server/templates/cas_server/samlValidate.xml b/cas_server/templates/cas_server/samlValidate.xml new file mode 100644 index 0000000..3943dec --- /dev/null +++ b/cas_server/templates/cas_server/samlValidate.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + https://some-service.example.com/app/ + + + + + + {{username}} + + + urn:oasis:names:tc:SAML:1.0:cm:artifact + + + +{% for name, value in attributes %} + + value + +{% endfor %} + + + + {{username}} + + + urn:oasis:names:tc:SAML:1.0:cm:artifact + + + + + + + + diff --git a/cas_server/templates/cas_server/samlValidateError.xml b/cas_server/templates/cas_server/samlValidateError.xml new file mode 100644 index 0000000..062337b --- /dev/null +++ b/cas_server/templates/cas_server/samlValidateError.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/cas_server/urls.py b/cas_server/urls.py index dac273a..9550fb5 100644 --- a/cas_server/urls.py +++ b/cas_server/urls.py @@ -14,5 +14,6 @@ urlpatterns = patterns('', url('^proxy$', views.proxy, name='proxy'), url('^p3/serviceValidate$', views.p3_serviceValidate, name='p3_serviceValidate'), url('^p3/proxyValidate$', views.p3_proxyValidate, name='p3_proxyValidate'), + url('^samlValidate$', views.samlValidate, name='samlValidate'), ) diff --git a/cas_server/views.py b/cas_server/views.py index fc0e3f2..40f4910 100644 --- a/cas_server/views.py +++ b/cas_server/views.py @@ -5,10 +5,12 @@ from django.shortcuts import render, redirect from django.http import HttpResponse, StreamingHttpResponse from django.conf import settings from django.contrib import messages +from django.views.decorators.csrf import csrf_exempt from django.utils.translation import ugettext as _ import requests from datetime import datetime, timedelta +from lxml import etree import utils import forms @@ -218,3 +220,35 @@ def p3_serviceValidate(request): def p3_proxyValidate(request): return proxyValidate(request) + +@csrf_exempt +def samlValidate(request): + if request.method == 'POST': + target = request.GET.get('TARGET') + root = etree.fromstring(request.body) + try: + auth_req = root.getchildren()[1].getchildren()[0] + IssueInstant = auth_req.attrib['IssueInstant'] + RequestID = auth_req.attrib['RequestID'] + ticket = auth_req.getchildren()[0].text + ticket = models.ServiceTicket.objects.get(value=ticket, service=target, validate=False, creation__gt=(datetime.now() - timedelta(seconds=settings.CAS_TICKET_VALIDITY))) + ticket.validate = True + ticket.save() + expireInstant = (ticket.creation + timedelta(seconds=settings.CAS_TICKET_VALIDITY)).isoformat() + attributes = [] + for key, value in ticket.attributs.items(): + if isinstance(value, list): + for v in value: + attributes.append((key, v)) + else: + attributes.append((key, value)) + params = {'IssueInstant':IssueInstant, 'expireInstant':expireInstant,'Recipient':target, 'ResponseID':RequestID, 'username':ticket.user.username, 'attributes':attributes} + if ticket.service_pattern.user_field and ticket.user.attributs.get(ticket.service_pattern.user_field): + params['username'] = ticket.user.attributs.get(ticket.service_pattern.user_field) + return render(request, "cas_server/samlValidate.xml", params, content_type="text/xml; charset=utf-8") + except IndexError: + return render(request, "cas_server/samlValidateError.xml", {'code':'VersionMismatch'}, content_type="text/xml; charset=utf-8") + except KeyError: + return render(request, "cas_server/samlValidateError.xml", {'code':'VersionMismatch'}, content_type="text/xml; charset=utf-8") + except models.ServiceTicket.DoesNotExist: + return render(request, "cas_server/samlValidateError.xml", {'code':'AuthnFailed'}, content_type="text/xml; charset=utf-8")