1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
'''
Created on Apr 2, 2012
@author: leifj
'''
from saml2 import server, BINDING_SOAP
from saml2 import soap
from saml2 import config
import logging
from django.contrib.auth.models import User
from django.http import HttpResponse, HttpResponseBadRequest
from saml2.metadata import entity_descriptor
from saml2.saml import NAME_FORMAT_URI
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
from saml2.request import AttributeQuery
def get_full_path(request,path=None):
if path == None:
path = request.path
full_path = ('http', ('', 's')[request.is_secure()], '://', request.META['HTTP_HOST'], path)
return ''.join(full_path)
def _config(request):
host = request.get_host().replace(":","-")
c = {
"entityid" : get_full_path(request,"/saml2/entity"),
"description": "COIP",
"service": {
"aa": {
"name" : "COIP",
"endpoints" : {
"attribute_service" : [(get_full_path(request,"/saml2/aq"), BINDING_SOAP)],
},
"policy": {
"default": {
"lifetime": {"minutes":15},
"attribute_restrictions": None, # means all I have
"name_form": NAME_FORMAT_URI
},
},
"subject_data": ("dict", {}),
}
},
"debug" : 1,
"key_file" : "%s/%s.key" % (settings.SSL_KEY_DIR,host),
"cert_file" : "%s/%s.crt" % (settings.SSL_CRT_DIR,host),
"attribute_map_dir" : "%s/saml2/attributemaps" % settings.BASE_DIR,
"metadata" : {
"local": ["%s/saml2/metadata/sp.xml" % settings.BASE_DIR],
},
"organization": {
"display_name": "COIP on %s" % host,
"name": "COIP on %s" % host,
"url": get_full_path(request,"/"),
},
}
return c
def _aa_reply(aa, aq, user, sp_entityid):
consumer_url = aa.metadata.consumer_url(aq.issuer.text)
in_response_to = aq.id
name_id = aq.subject.name_id
logging.info("name_id: %s" % name_id)
return aa.do_aa_response(in_response_to,
consumer_url,
sp_entityid,
identity=user,
name_id=name_id,
issuer=aa.conf.entityid)
def metadata(request):
cnf = config.Config().load(_config(request), metadata_construction=True)
ed = entity_descriptor(cnf, 0)
return HttpResponse(content=ed,content_type="text/xml")
def parse_attribute_query(aa, xml_string, decode=True):
""" Parse an attribute query
:param xml_string: The Attribute Query as an XML string
:param decode: Whether the xmlstring is base64encoded and zipped
:return: 3-Tuple containing:
subject - identifier of the subject
attribute - which attributes that the requestor wants back
query - the whole query
"""
receiver_addresses = aa.conf.endpoint("attribute_service")
attribute_query = AttributeQuery( aa.sec, receiver_addresses)
logging.debug(xml_string)
attribute_query = attribute_query.loads(xml_string, decode=decode)
logging.info(repr(attribute_query))
attribute_query = attribute_query.verify()
logging.info(repr(attribute_query))
#logging.info("KEYS: %s" % attribute_query.message.keys())
# Subject is described in the a saml.Subject instance
subject = attribute_query.subject_id()
attribute = attribute_query.attribute()
return subject, attribute, attribute_query.message
@csrf_exempt
def aq(request):
if request.method == 'POST':
cnf = config.Config().load(_config(request))
cnf.context = 'aa'
aa = server.Server(config=cnf, log=logging, debug=1, stype="aa")
request_xml = soap.parse_soap_enveloped_saml_attribute_query(request.raw_post_data)
logging.debug(request_xml)
(subject, attribute, aq) = parse_attribute_query(aa,request_xml,False)
sp_entityid = aq.issuer.text
claims = {}
try:
logging.debug("Subject: %s" % subject.text)
user = User.objects.get(username=subject.text)
p = user.get_profile()
claims = {'uid': user.username,'displayName': p.display_name}
except Exception,exc:
logging.debug(exc)
pass
aa_response = _aa_reply(aa, aq, claims, sp_entityid)
xml = soap.make_soap_enveloped_saml_thingy(aa_response)
logging.debug(xml)
return HttpResponse(content=xml, content_type="application/soap+xml")
else:
return HttpResponseBadRequest("<html><head><title>No</title></head><body><h1>Bad Request</h1><p>Go sell crazy someplace else, we're all stocked up here!</p></body></html>")
|