SAMLv2 conformance fixes (encryption settings, ECP, affiliations, etc.)

git-svn-id: svn://localhost/lasso-conform/trunk@33 2a3a78c3-912c-0410-af21-e1fb2d1df599
This commit is contained in:
fpeters 2006-12-07 15:36:55 +00:00
parent d5899ed8a6
commit e7135c0be4
1 changed files with 89 additions and 9 deletions

View File

@ -94,7 +94,7 @@ class LoginDirectory(Directory):
class RootDirectory(Directory):
_q_exports = ['', 'admin', 'backoffice', 'login', 'logout', 'liberty', 'saml',
'ident', 'register', 'info']
'ident', 'register', 'info', 'encryption', 'replay_artifact']
def _q_index [html] (self):
template.html_top('Lasso Conformance SP')
@ -109,7 +109,8 @@ class RootDirectory(Directory):
http_accept = request.environ.get('HTTP_ACCEPT')
http_poas = request.environ.get('HTTP_PAOS')
if http_accept != 'application/vnd.paos+xml' and http_poas != 'urn:liberty:paos:2003-08':
if 'application/vnd.paos+xml' not in http_accept or \
'urn:liberty:paos:2003-08' not in http_poas:
return template.error_page(_('Invalid PAOS Request'))
server = misc.get_lasso_server(protocol = 'saml2')
@ -121,13 +122,20 @@ class RootDirectory(Directory):
login.request.nameIDPolicy.format = lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT
login.request.nameIDPolicy.allowCreate = True
login.request.forceAuthn = False
login.request.isPassive = True
login.request.isPassive = False
login.request.consent = 'urn:oasis:names:tc:SAML:2.0:consent:current-implicit'
login.request.protocolBinding = lasso.SAML2_METADATA_BINDING_SOAP
login.request.protocolBinding = lasso.SAML2_METADATA_BINDING_PAOS
if False:
# NTT ECP requires this:
login.request.requestedAuthnContext = lasso.Samlp2RequestedAuthnContext()
t = lasso.StringList()
t.append('urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorContract')
login.request.requestedAuthnContext.authnContextClassRef = t
login.buildAuthnRequestMsg()
response = get_response()
response.set_content_type('text/xml')
response.set_content_type('application/vnd.paos+xml', 'UTF-8')
response.set_header('PAOS', 'ver=urn:liberty:paos:2003-08;urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp')
return login.msgBody
def unlogged_page [html] (self):
@ -148,7 +156,7 @@ class RootDirectory(Directory):
('transient', _('Transient')),
('encrypted', _('Encrypted')),
('none', _('(none)'))])
# XXX: affiliation
form.add(StringWidget, 'affiliation', title = _('Affiliation'))
form.add(SingleSelectWidget, 'consent',
title = _('Consent'),
options = ['', 'obtained', 'prior', 'current-implicit',
@ -173,12 +181,12 @@ class RootDirectory(Directory):
form.add_submit('intro', _('Get IdP via Introduction Cookie'))
elif get_session().saml_idp_cookie:
common_domain = get_cfg('sp', {}).get('common_domain')
intro_cookie_q = urllib.unquote(get_session().saml_idp_cookie)
intro_cookie_q = urllib.unquote_plus(get_session().saml_idp_cookie)
splitted_cookie = [x for x in intro_cookie_q.split(str(' ')) if x]
last_id = splitted_cookie[-1]
v = misc.get_provider_key(base64.decodestring(last_id))
form.add_submit('intro-%s' % v,
_('Log on using IdP discovered from IdP Introduction'))
_('Log on using IdP discovered from IdP Introduction (%s)') % v)
if form.is_submitted():
return self.do_login(form)
@ -192,6 +200,10 @@ class RootDirectory(Directory):
_('Service Provider not configured to use IdP Introduction Cookie')
'</p>'
'<p>'
'Sample <a href="/data/affiliations.xml">affiliations</a> file to download'
'</p>'
def loggedin_page [html] (self):
identity_dump = get_request().user.lasso_dump
session_dump = get_session().lasso_session_dump
@ -223,15 +235,38 @@ class RootDirectory(Directory):
'<p>%s</p>' % _('Logged in (%s)') % get_request().user.display_name
if get_request().user.anonymous:
'<a href="register">%s</a>' % _('Register')
if identity_dump:
'<strong><a href="register">%s</a></strong>' % _('Register')
'<pre>'
get_session().lasso_identity_provider_id
'</pre>'
'<pre>'
get_session().name_identifier
'</pre>'
'<div id="logged-in-options">'
form.render()
'</div>'
if os.path.exists(str('/tmp/artifact-msg-url')):
'<p>'
'<a href="replay_artifact">%s</a>' % _('Replay last artifact response')
'</p>'
def replay_artifact [html] (self):
msg_url = file(str('/tmp/artifact-msg-url')).read()
msg_body = file(str('/tmp/artifact-msg-body')).read()
from qommon.liberty import soap_call
soap_answer = soap_call(msg_url, msg_body)
open(str('/tmp/replayed-artifact.xml'), str('w')).write(soap_answer)
formatted = os.popen(str('xmllint --format /tmp/replayed-artifact.xml')).read()
template.html_top(_('Artifact Replayed'))
'<pre>'
formatted
'</pre>'
def register [html] (self):
if not get_request().user:
@ -318,6 +353,10 @@ class RootDirectory(Directory):
if consent:
login.request.consent = 'urn:oasis:names:tc:SAML:2.0:consent:%s' % consent
affiliation = form.get_widget('affiliation').parse()
if affiliation:
login.request.nameIDPolicy.spNameQualifier = affiliation
# XXX: authn_context
login.buildAuthnRequestMsg()
@ -363,6 +402,47 @@ class RootDirectory(Directory):
return Directory._q_traverse(self, path)
def encryption [html] (self):
form = Form(enctype='multipart/form-data')
options = []
for klp, lp in get_cfg('idp', {}).items():
try:
label = misc.get_provider_label(misc.get_provider(klp))
except KeyError:
continue
options.append((klp, label, klp))
options.sort()
for klp, label, klp2 in options:
form.add(HtmlWidget, '<h3>%s</h3>' % label)
form.add(CheckboxWidget, 'encrypt_nameid_%s' % klp,
title = _('Encrypt NameID'),
value = get_cfg('idp')[klp].get('encrypt_nameid'))
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
if form.is_submitted():
self.encryption_submit(form, options)
return redirect('.')
template.html_top()
if not get_cfg('sp').has_key('encryption_privatekey'):
'<div class="errornotice">'
_('There is currently no encryption key set on this server.')
'</div>'
form.render()
def encryption_submit(self, form, options):
for klp, label, klp2 in options:
get_cfg('idp')[klp]['encrypt_nameid'] = form.get_widget(
'encrypt_nameid_%s' % klp).parse()
get_publisher().write_cfg()
def _q_lookup(self, component):
if component == 'themes':
dirname = os.path.join(get_publisher().data_dir, 'themes')