def _process_AuthnStatement(self, subject, s): info = dict( name_qualifier=subject.NameQualifier, nameid_format=subject.Format, sp_name_qualifier=subject.SPNameQualifier, nameid=subject.value(), authn_time=pyxb_to_datetime(as_utc(s.AuthnInstant)), valid_until=pyxb_to_datetime(as_utc(s.SessionNotOnOrAfter)), session_id=s.SessionIndex, authn_context_class=s.AuthnContext.AuthnContextClassRef, ) info["user_id"] = self.format_user_id(info) self._set_cookie(self.session_cookie_name, info)
def is_valid(self, context=None): # according to 2.5.1.1 we should implement a three-value logic # (invalid, valid, indeterminate) -- we fail to do so. now = utcnow() cv = self.NotBefore if cv is not None and now < as_utc(cv): return False cv = self.NotOnOrAfter if cv is not None and now >= as_utc(cv): return False for c in self.Condition: if not c.is_valid(context): return False for c in self.AudienceRestriction: if not c.is_valid(context): return False for c in self.OneTimeUse: if not c.is_valid(context): return False for c in self.ProxyRestriction: pass return True
def _process_assertion(self, ass, context): # ensure we know the issuer -- an exception results, if not eid = ass.Issuer.value() auth = self._get_authority() auth.metadata_by_id(eid) if not ass.verified_signature(): raise SamlError("assertion %s was not signed by the issuer" % ass.ID) if not ass.is_valid(context): raise SamlError("assertion %s is not valid" % ass.ID) if context.binding == "post": # check the `SubjectConfirmation` condition of the `Browser SSO profile` ok = False for sc in ass.Subject.SubjectConfirmation: scm = sc.Method if scm != "urn:oasis:names:tc:SAML:2.0:cm:bearer": # we do not understand the method -- hope, we find one we understand continue scd = sc.SubjectConfirmationData if scd is None: continue # not valid if scd.NotOnOrAfter is None or utcnow() >= as_utc( scd.NotOnOrAfter): continue # not valid if scd.Recipient != context.rsp.Destination: continue # not valid if scd.InResponseTo != context.rsp.InResponseTo: continue # not valid # XXX Jazkarta Note: NYU is on a private network, so we get an address # mismatch here. At the point at which we want to remove # client-specific customizations, we'll have to monkey patch this # method or find some other means of overriding this check: # if scd.Address and context.zrequest.getClientAddr() != scd.Address: # continue # not valid ok = True break if not ok: raise SamlError( "subject confirmation in assertion %s is invalid" % ass.ID) subject = ass.Subject.NameID for tag in ("Statement", "AuthnStatement", "AuthzDecisionStatement", "AttributeStatement"): for s in getattr(ass, tag): # process statement -- "AttributeError", if we do not support its type getattr(self, "_process_" + tag)(subject, s)
def _process_assertion(self, ass, context): # ensure we know the issuer -- an exception results, if not eid = ass.Issuer.value() auth = self._get_authority() auth.metadata_by_id(eid) if not ass.verified_signature(): raise SamlError("assertion %s was not signed by the issuer" % ass.ID) if not ass.is_valid(context): raise SamlError("assertion %s is not valid" % ass.ID) if context.binding == "post": # check the `SubjectConfirmation` condition of the `Browser SSO profile` ok = False for sc in ass.Subject.SubjectConfirmation: scm = sc.Method if scm != "urn:oasis:names:tc:SAML:2.0:cm:bearer": # we do not understand the method -- hope, we find one we understand continue scd = sc.SubjectConfirmationData if scd is None: continue # not valid if scd.NotOnOrAfter is None or utcnow() >= as_utc(scd.NotOnOrAfter): continue # not valid if scd.Recipient != context.rsp.Destination: continue # not valid if scd.InResponseTo != context.rsp.InResponseTo: continue # not valid if scd.Address and context.zrequest.getClientAddr() != scd.Address: continue # not valid ok = True break if not ok: raise SamlError("subject confirmation in assertion %s is invalid" % ass.ID) subject = ass.Subject.NameID for tag in ("Statement", "AuthnStatement", "AuthzDecisionStatement", "AttributeStatement"): for s in getattr(ass, tag): # process statement -- "AttributeError", if we do not support its type getattr(self, "_process_" + tag)(subject, s)