def test05(self): '''SAMLv2 Authn request emitted and received using Artifact binding''' sp = lasso.Server(os.path.join(dataDir, 'sp5-saml2/metadata.xml'), os.path.join(dataDir, 'sp5-saml2/private-key.pem')) assert sp sp.addProvider(lasso.PROVIDER_ROLE_IDP, os.path.join(dataDir, 'idp5-saml2/metadata.xml')) sp_login = lasso.Login(sp) assert sp_login sp_login.initAuthnRequest(None, lasso.HTTP_METHOD_ARTIFACT_GET) sp_login.buildAuthnRequestMsg() sp_login_dump = sp_login.dump() idp = lasso.Server(os.path.join(dataDir, 'idp5-saml2/metadata.xml'), os.path.join(dataDir, 'idp5-saml2/private-key.pem')) idp.addProvider(lasso.PROVIDER_ROLE_SP, os.path.join(dataDir, 'sp5-saml2/metadata.xml')) idp_login = lasso.Login(idp) idp_login.initRequest( sp_login.msgUrl.split('?')[1], lasso.HTTP_METHOD_ARTIFACT_GET) idp_login.buildRequestMsg() sp_login2 = lasso.Login.newFromDump(sp, sp_login_dump) assert isinstance(sp_login2, lasso.Login) assert idp_login.msgBody sp_login2.processRequestMsg(idp_login.msgBody) sp_login2.buildResponseMsg() assert sp_login2.msgBody try: idp_login.processResponseMsg(sp_login2.msgBody) except: raise assert isinstance(idp_login.request, lasso.Samlp2AuthnRequest)
def login(self, sp, idp, user_id, federations, sp_identity_dump=None, sp_session_dump=None, idp_identity_dump=None, idp_session_dump=None): sp_login = lasso.Login(sp) idp_provider_id = 'http://idp5/metadata' sp_login.initAuthnRequest(idp_provider_id, lasso.HTTP_METHOD_REDIRECT) sp_login.request.nameIDPolicy.format = lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT sp_login.request.nameIDPolicy.allowCreate = True sp_login.buildAuthnRequestMsg() idp_login = lasso.Login(idp) query = sp_login.msgUrl.split('?')[1] if idp_identity_dump is not None: idp_login.setIdentityFromDump(idp_identity_dump) if idp_session_dump is not None: idp_login.setSessionFromDump(idp_session_dump) idp_login.processAuthnRequestMsg(query) idp_login.validateRequestMsg(True, True) idp_login.buildAssertion(lasso.SAML_AUTHENTICATION_METHOD_PASSWORD, None, None, None, None) if idp_login.assertion.subject.encryptedId: f = self.nid2tuple(idp_login.assertion.subject.encryptedId.originalData) else: f = self.nid2tuple(idp_login.assertion.subject.nameId) federations[f] = user_id l = federations.get(user_id, []) l.append(f) federations[user_id] = l idp_login.idwsf2AddDiscoveryBootstrapEpr(url = idpSoapEndpoint, abstract = 'Discovery Service', security_mechanisms = (lasso.SECURITY_MECH_BEARER,)) idp_login.buildArtifactMsg(lasso.HTTP_METHOD_ARTIFACT_GET) artifact_message = idp_login.artifactMessage if idp_login.isIdentityDirty: idp_identity_dump = idp_login.identity.dump() if idp_login.isSessionDirty: idp_session_dump = idp_login.session.dump() sp_login = lasso.Login(sp) query = idp_login.msgUrl.split('?')[1] query = query.replace("%3D", "=") sp_login.initRequest(query, lasso.HTTP_METHOD_ARTIFACT_GET) sp_login.buildRequestMsg() idp_login = lasso.Login(idp) idp_login.processRequestMsg(sp_login.msgBody) idp_login.artifactMessage = artifact_message idp_login.buildResponseMsg(None) sp_login.processResponseMsg(idp_login.msgBody) sp_login.acceptSso() if sp_login.isIdentityDirty: sp_identity_dump = sp_login.identity.dump() if sp_login.isSessionDirty: sp_session_dump = sp_login.session.dump() return sp_identity_dump, sp_session_dump, idp_identity_dump, idp_session_dump, sp_login.idwsf2GetDiscoveryBootstrapEpr()
def process_authn_request_redirect(self, url, auth_result=True, consent=True): login = lasso.Login(self.server) login.processAuthnRequestMsg(url.split('?', 1)[1]) # See # https://docs.python.org/2/library/zlib.html#zlib.decompress # for the -15 magic value. # # * -8 to -15: Uses the absolute value of wbits as the window size # logarithm. The input must be a raw stream with no header or trailer. # # it means Deflate instead of GZIP (same stream no header, no trailer) self.request = zlib.decompress( base64.b64decode( urlparse.parse_qs( urlparse.urlparse(url).query)['SAMLRequest'][0]), -15) try: login.validateRequestMsg(auth_result, consent) except lasso.LoginRequestDeniedError: pass else: login.buildAssertion(lasso.SAML_AUTHENTICATION_METHOD_PASSWORD, "FIXME", "FIXME", "FIXME", "FIXME") if login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_ART: login.buildArtifactMsg(lasso.HTTP_METHOD_ARTIFACT_GET) self.artifact = login.artifact self.artifact_message = login.artifactMessage elif login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_POST: login.buildAuthnResponseMsg() else: raise NotImplementedError return login.msgUrl, login.msgBody, login.msgRelayState
def artifact_resolve(request, soap_message): '''Resolve a SAMLv1.1 ArtifactResolve request ''' server = create_idff12_server(request, reverse(metadata)) login = lasso.Login(server) try: login.processRequestMsg(soap_message) except: raise logging.debug('ID-FFv1.2 artifact resolve %r' % soap_message) liberty_artifact = LibertyArtifact.objects.get( artifact=login.assertionArtifact) if liberty_artifact: liberty_artifact.delete() provider_id = liberty_artifact.provider_id load_provider(request, provider_id, server=login.server) load_session(request, login, session_key=liberty_artifact.django_session_key) logging.info('ID-FFv1.2 artifact resolve from %r for artifact %r' % (provider_id, login.assertionArtifact)) else: logging.warning('ID-FFv1.2 no artifact found for %r' % login.assertionArtifact) provider_id = None return finish_artifact_resolve( request, login, provider_id, session_key=liberty_artifact.django_session_key)
def test04(self): """Conversion of a lib:AuthnRequest with extensions into a query and back.""" sp = lasso.Server( os.path.join(dataDir, 'sp1-la/metadata.xml'), os.path.join(dataDir, 'sp1-la/private-key-raw.pem'), None, os.path.join(dataDir, 'sp1-la/certificate.pem')) sp.addProvider( lasso.PROVIDER_ROLE_IDP, os.path.join(dataDir, 'idp1-la/metadata.xml'), os.path.join(dataDir, 'idp1-la/public-key.pem'), os.path.join(dataDir, 'idp1-la/certificate.pem')) spLogin = lasso.Login(sp) spLogin.initAuthnRequest() requestAuthnContext = lasso.LibRequestAuthnContext() extensionList = [] for extension in ( '<action>do</action>', '<action2>do action 2</action2><action3>do action 3</action3>'): extensionList.append( '<lib:Extension xmlns:lib="urn:liberty:iff:2003-08">%s</lib:Extension>' % extension) spLogin.request.extension = tuple(extensionList) spLogin.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_ART spLogin.buildAuthnRequestMsg() authnRequestUrl = spLogin.msgUrl authnRequestQuery = spLogin.msgUrl[spLogin.msgUrl.index('?') + 1:] idp = lasso.Server( os.path.join(dataDir, 'idp1-la/metadata.xml'), os.path.join(dataDir, 'idp1-la/private-key-raw.pem'), None, os.path.join(dataDir, 'idp1-la/certificate.pem')) idp.addProvider( lasso.PROVIDER_ROLE_SP, os.path.join(dataDir, 'sp1-la/metadata.xml'), os.path.join(dataDir, 'sp1-la/public-key.pem'), os.path.join(dataDir, 'sp1-la/certificate.pem')) idpLogin = lasso.Login(idp) idpLogin.processAuthnRequestMsg(authnRequestQuery) self.failUnless(idpLogin.request.extension) extensionsList = idpLogin.request.extension self.failUnlessEqual(len(extensionsList), 1) self.failUnless('<action>do</action>' in extensionsList[0]) self.failUnless('<action2>do action 2</action2>' in extensionsList[0]) self.failUnless('<action3>do action 3</action3>' in extensionsList[0])
def test_06(self): '''Login test between SP and IdP with encrypted private keys''' sp_server = server('sp7-saml2', lasso.PROVIDER_ROLE_IDP, 'idp7-saml2') idp_server = server('idp7-saml2', lasso.PROVIDER_ROLE_SP, 'sp7-saml2') sp_login = lasso.Login(sp_server) sp_login.initAuthnRequest() sp_login.request.protocolBinding = lasso.SAML2_METADATA_BINDING_POST; sp_login.buildAuthnRequestMsg() idp_login = lasso.Login(idp_server) idp_login.setSignatureVerifyHint(lasso.PROFILE_SIGNATURE_VERIFY_HINT_FORCE) idp_login.processAuthnRequestMsg(sp_login.msgUrl.split('?')[1]) idp_login.validateRequestMsg(True, True) idp_login.buildAssertion("None", "None", "None", "None", "None") idp_login.buildAuthnResponseMsg() sp_login.setSignatureVerifyHint(lasso.PROFILE_SIGNATURE_VERIFY_HINT_FORCE) sp_login.processAuthnResponseMsg(idp_login.msgBody) sp_login.acceptSso()
def _get_lasso_for_provider(self): """internal helper to get a configured lasso.Login object for the given provider id""" # TODO: we should cache those results somewhere because it is # really costly to always recreate a login variable from buffers server = lasso.Server.newFromBuffers(self.sp_metadata, self.sp_pkey) server.addProviderFromBuffer(lasso.PROVIDER_ROLE_IDP, self.idp_metadata) return lasso.Login(server)
def test03(self): """Conversion of a lib:AuthnRequest with an AuthnContext into a query and back.""" sp = lasso.Server( os.path.join(dataDir, 'sp1-la/metadata.xml'), os.path.join(dataDir, 'sp1-la/private-key-raw.pem'), None, os.path.join(dataDir, 'sp1-la/certificate.pem')) sp.addProvider( lasso.PROVIDER_ROLE_IDP, os.path.join(dataDir, 'idp1-la/metadata.xml'), os.path.join(dataDir, 'idp1-la/public-key.pem'), os.path.join(dataDir, 'idp1-la/certificate.pem')) spLogin = lasso.Login(sp) spLogin.initAuthnRequest() requestAuthnContext = lasso.LibRequestAuthnContext() authnContextClassRefsList = [] authnContextClassRefsList.append( lasso.LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD) requestAuthnContext.authnContextClassRef = tuple(authnContextClassRefsList) spLogin.request.requestAuthnContext = requestAuthnContext spLogin.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_ART spLogin.buildAuthnRequestMsg() authnRequestUrl = spLogin.msgUrl authnRequestQuery = spLogin.msgUrl[spLogin.msgUrl.index('?') + 1:] idp = lasso.Server( os.path.join(dataDir, 'idp1-la/metadata.xml'), os.path.join(dataDir, 'idp1-la/private-key-raw.pem'), None, os.path.join(dataDir, 'idp1-la/certificate.pem')) idp.addProvider( lasso.PROVIDER_ROLE_SP, os.path.join(dataDir, 'sp1-la/metadata.xml'), os.path.join(dataDir, 'sp1-la/public-key.pem'), os.path.join(dataDir, 'sp1-la/certificate.pem')) idpLogin = lasso.Login(idp) idpLogin.processAuthnRequestMsg(authnRequestQuery) self.failUnless(idpLogin.request.requestAuthnContext) authnContextClassRefsList = idpLogin.request.requestAuthnContext.authnContextClassRef self.failUnlessEqual(len(authnContextClassRefsList), 1) self.failUnlessEqual(authnContextClassRefsList[0], lasso.LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD)
def resolve_artifact(self, soap_message): login = lasso.Login(self.server) login.processRequestMsg(soap_message) if hasattr(self, 'artifact') and self.artifact == login.artifact: # artifact is known, go on ! login.artifactMessage = self.artifact_message # forget the artifact del self.artifact del self.artifact_message login.buildResponseMsg() return login.msgBody
def resolve_artifact(self, soap_message): login = lasso.Login(self.server) login.processRequestMsg(soap_message) assert 'rsa-sha256' in soap_message if hasattr(self, 'artifact') and self.artifact == login.artifact: # artifact is known, go on ! login.artifactMessage = self.artifact_message # forget the artifact del self.artifact del self.artifact_message login.buildResponseMsg() assert 'rsa-sha256' in login.msgBody return '<?xml version="1.0"?>\n' + login.msgBody
def test07(self): '''SAMLv2 SSO with DSA key for the IdP''' sp = lasso.Server(os.path.join(dataDir, 'sp5-saml2/metadata.xml'), os.path.join(dataDir, 'sp5-saml2/private-key.pem')) assert sp sp.addProvider(lasso.PROVIDER_ROLE_IDP, os.path.join(dataDir, 'idp12-dsa-saml2/metadata.xml')) sp_login = lasso.Login(sp) assert sp_login sp_login.initAuthnRequest(None, lasso.HTTP_METHOD_REDIRECT) sp_login.buildAuthnRequestMsg() idp = lasso.Server( os.path.join(dataDir, 'idp12-dsa-saml2/metadata.xml'), os.path.join(dataDir, 'idp12-dsa-saml2/private-key.pem')) idp.signatureMethod = lasso.SIGNATURE_METHOD_DSA_SHA1 idp.addProvider(lasso.PROVIDER_ROLE_SP, os.path.join(dataDir, 'sp5-saml2/metadata.xml')) idp_login = lasso.Login(idp) idp_login.processAuthnRequestMsg(sp_login.msgUrl.split('?')[1]) idp_login.protocolProfile = lasso.LOGIN_PROTOCOL_PROFILE_BRWS_POST idp_login.validateRequestMsg(True, True) idp_login.buildAssertion("None", "None", "None", "None", "None") idp_login.buildAuthnResponseMsg()
def login(self, sp, idp): sp_login = lasso.Login(sp) sp_login.initAuthnRequest(sp.providerIds[0], lasso.HTTP_METHOD_POST) sp_login.request.nameIdPolicy = lasso.LIB_NAMEID_POLICY_TYPE_FEDERATED sp_login.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_POST sp_login.buildAuthnRequestMsg() idp_login = lasso.Login(idp) idp_login.processAuthnRequestMsg(sp_login.msgBody) idp_login.validateRequestMsg(True, True) # Set a resource offering in the assertion discovery_resource_id = "http://idp/discovery/resources/1" idp_login.setResourceId(discovery_resource_id) idp_login.buildAssertion(lasso.SAML_AUTHENTICATION_METHOD_PASSWORD, None, None, None, None) idp_login.buildAuthnResponseMsg() sp_login = lasso.Login(sp) sp_login.processAuthnResponseMsg(idp_login.msgBody) sp_login.acceptSso() return sp_login.identity.dump(), sp_login.session.dump( ), idp_login.identity.dump(), idp_login.session.dump()
def idp_sso(request, provider_id, user_id=None): '''Initiate an SSO toward provider_id without a prior AuthnRequest ''' assert provider_id, 'You must call idp_initiated_sso with a provider_id parameter' server = create_idff12_server(request, reverse(metadata)) login = lasso.Login(server) liberty_provider = load_provider(request, provider_id, server=login.server) service_provider = liberty_provider.service_provider binding = service_provider.prefered_assertion_consumer_binding nid_policy = service_provider.default_name_id_format if user_id: user = User.get(id=user_id) if not check_delegated_authentication_permission(request): logging.warning( 'ID-FFv1.2: %r tried to log as %r on %r but was forbidden' % (request.user, user, provider_id)) return HttpResponseForbidden( 'You must be superuser to log as another user') else: user = request.user load_federation(request, login, user) if not liberty_provider: message = _('ID-FFv1.2: provider %r unknown') % provider_id logging.warning('ID-FFv1.2: provider %r unknown' % provider_id) return HttpResponseForbidden(message) login.initIdpInitiatedAuthnRequest(provider_id) if binding == 'art': login.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_ART elif binding == 'post': login.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_POST else: raise Exception('Unsupported binding %r' % binding) if nid_policy == 'persistent': login.request.nameIdPolicy = lasso.LIB_NAMEID_POLICY_TYPE_FEDERATED elif nid_policy == 'transient': login.request.nameIdPolicy = lasso.LIB_NAMEID_POLICY_TYPE_ONE_TIME else: message = _( 'ID-FFv1.2: default nameIdPolicy unsupported %r') % nid_policy logging.error(message) raise Exception(message) login.processAuthnRequestMsg(None) return sso_after_process_request(request, login, consent_obtained=True, user=user, save=False)
def sso(request): """Endpoint for AuthnRequests asynchronously sent, i.e. POST or Redirect""" # 1. Process the request, separate POST and GET treatment message = get_idff12_request_message(request) if not message: return HttpResponseForbidden('Invalid SAML 1.1 AuthnRequest: "%s"' % message) server = create_idff12_server(request, reverse(metadata)) login = lasso.Login(server) while True: try: logging.debug('ID-FFv1.2: processing sso request %r' % message) login.processAuthnRequestMsg(message) break except lasso.ProfileInvalidMsgError: message = _('Invalid SAML 1.1 AuthnRequest: %r') % message logging.error(message) return HttpResponseForbidden(message) except lasso.DsInvalidSignatureError: message = _( 'Invalid signature on SAML 1.1 AuthnRequest: %r') % message logging.error(message) # This error is handled through SAML status codes, so return a # response return finish_sso(request, login) except lasso.ServerProviderNotFoundError: # This path is not exceptionnal it should be normal since we did # not load any provider in the Server object provider_id = login.remoteProviderId # 2. Lookup the ProviderID logging.info('ID-FFv1.2: AuthnRequest from %r' % provider_id) provider_loaded = load_provider(request, provider_id, server=login.server) if not provider_loaded: consent_obtained = False message = _('ID-FFv1.2: provider %r unknown') % provider_id logging.warning(message) return HttpResponseForbidden(message) else: # XXX: does consent be always automatic for known providers ? Maybe # add a configuration key on the provider. consent_obtained = True return sso_after_process_request(request, login, consent_obtained=consent_obtained)
def test06(self): """Get & set attributes of nodes of type node.""" login = lasso.Login( lasso.Server(os.path.join(dataDir, 'sp1-la/metadata.xml'), os.path.join(dataDir, 'sp1-la/private-key-raw.pem'), None, os.path.join(dataDir, 'sp1-la/certificate.pem'))) self.failUnlessEqual(login.request, None) login.request = lasso.LibAuthnRequest() login.request.consent = lasso.LIB_CONSENT_OBTAINED self.failUnlessEqual(login.request.consent, lasso.LIB_CONSENT_OBTAINED) login.request = None self.failUnlessEqual(login.request, None) del login
def test01(self): """SP login; testing access to authentication request.""" lassoServer = lasso.Server( os.path.join(dataDir, 'sp1-la/metadata.xml'), os.path.join(dataDir, 'sp1-la/private-key-raw.pem'), None, os.path.join(dataDir, 'sp1-la/certificate.pem')) lassoServer.addProvider( lasso.PROVIDER_ROLE_IDP, os.path.join(dataDir, 'idp1-la/metadata.xml'), os.path.join(dataDir, 'idp1-la/public-key.pem'), os.path.join(dataDir, 'idp1-la/certificate.pem')) login = lasso.Login(lassoServer) login.initAuthnRequest() login.request login.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_ART self.failUnlessEqual(login.request.protocolProfile, lasso.LIB_PROTOCOL_PROFILE_BRWS_ART)
def test02(self): """SP login; testing processing of an empty Response.""" lassoServer = lasso.Server( os.path.join(dataDir, 'sp1-la/metadata.xml'), os.path.join(dataDir, 'sp1-la/private-key-raw.pem'), None, os.path.join(dataDir, 'sp1-la/certificate.pem')) lassoServer.addProvider( lasso.PROVIDER_ROLE_IDP, os.path.join(dataDir, 'idp1-la/metadata.xml'), os.path.join(dataDir, 'idp1-la/public-key.pem'), os.path.join(dataDir, 'idp1-la/certificate.pem')) login = lasso.Login(lassoServer) try: login.processResponseMsg('') except lasso.Error as error: if error[0] != lasso.PROFILE_ERROR_INVALID_MSG: raise
def make_authn_request(self, idp=None, method=lasso.HTTP_METHOD_REDIRECT, allow_create=None, format=None, relay_state=None, force_authn=None, is_passive=None, sp_name_qualifier=None, sign=False, name_id_policy=True): server = self.get_server() login = lasso.Login(server) if not sign: login.setSignatureHint(lasso.PROFILE_SIGNATURE_HINT_FORBID) login.initAuthnRequest(idp, method) request = login.request policy = request.nameIdPolicy if force_authn is not None: request.forceAuthn = force_authn if is_passive is not None: request.isPassive = is_passive if allow_create is not None: policy.allowCreate = allow_create if format is not None: policy.format = format if sp_name_qualifier is not None: policy.spNameQualifier = sp_name_qualifier if relay_state is not None: login.msgRelayState = relay_state if not name_id_policy: request.nameIdPolicy = None login.buildAuthnRequestMsg() if method == lasso.HTTP_METHOD_REDIRECT: self.assertIsNone(login.msgBody, 'body should be None with ' 'method Redirect') elif method == lasso.HTTP_METHOD_POST: self.assertIsNotNone(login.msgBody) self.assertIsNone(login.msgBody, 'body should be None with method ' 'Redirect') url_parsed = urlparse.urlparse(login.msgUrl) self.assertEqual(url_parsed.path, reverse('a2-idp-saml-sso'), 'msgUrl should target the sso endpoint') return login.msgUrl, login.msgBody, request.id
def process_authn_request_redirect(self, url, auth_result=True, consent=True): login = lasso.Login(self.server) login.processAuthnRequestMsg(url.split('?', 1)[1]) try: login.validateRequestMsg(auth_result, consent) except lasso.LoginRequestDeniedError: pass else: login.buildAssertion(lasso.SAML_AUTHENTICATION_METHOD_PASSWORD, "FIXME", "FIXME", "FIXME", "FIXME") if login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_ART: login.buildArtifactMsg(lasso.HTTP_METHOD_ARTIFACT_GET) self.artifact = login.artifact self.artifact_message = login.artifactMessage elif login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_POST: login.buildAuthnResponseMsg() else: raise NotImplementedError return login.msgUrl, login.msgBody
def get_login_handler(self, dump=None): if dump: return lasso.Login.newFromDump(self.server, dump) else: return lasso.Login(self.server)
def create_login(request): server = create_server(request) login = lasso.Login(server) if not app_settings.PRIVATE_KEY and not app_settings.PRIVATE_KEYS: login.setSignatureHint(lasso.PROFILE_SIGNATURE_HINT_FORBID) return login
def parse_authn_response(self, saml_response): server = self.get_server() login = lasso.Login(server) login.processAuthnResponseMsg(saml_response) login.acceptSso() return login
def get_login(self): """create a new login instance for each request. """ return lasso.Login(self.server)
def process_authn_request_redirect(self, url, auth_result=True, consent=True, msg=None): login = lasso.Login(self.server) login.processAuthnRequestMsg(url.split('?', 1)[1]) # See # https://docs.python.org/2/library/zlib.html#zlib.decompress # for the -15 magic value. # # * -8 to -15: Uses the absolute value of wbits as the window size # logarithm. The input must be a raw stream with no header or trailer. # # it means Deflate instead of GZIP (same stream no header, no trailer) self.request = zlib.decompress( base64.b64decode( urlparse.parse_qs( urlparse.urlparse(url).query)['SAMLRequest'][0]), -15) assert 'rsa-sha256' in url try: login.validateRequestMsg(auth_result, consent) except lasso.LoginRequestDeniedError: pass else: login.buildAssertion(lasso.SAML_AUTHENTICATION_METHOD_PASSWORD, datetime.datetime.now().isoformat(), None, datetime.datetime.now().isoformat(), datetime.datetime.now().isoformat()) def add_attribute(name, *values, **kwargs): fmt = kwargs.get('fmt', lasso.SAML2_ATTRIBUTE_NAME_FORMAT_BASIC) statements = login.response.assertion[ 0].attributeStatement or [lasso.Saml2AttributeStatement()] statement = statements[0] login.response.assertion[0].attributeStatement = statements attributes = list(statement.attribute) for attribute in attributes: if attribute.name == name and attribute.nameFormat == fmt: break else: attribute = lasso.Saml2Attribute() attributes.append(attribute) statement.attribute = attributes attribute_values = list(attribute.attributeValue) atv = lasso.Saml2AttributeValue() attribute_values.append(atv) attribute.attributeValue = attribute_values value_any = [] for value in values: if isinstance(value, lasso.Node): value_any.append(value) else: mtn = lasso.MiscTextNode.newWithString( force_str(value)) mtn.textChild = True value_any.append(mtn) atv.any = value_any add_attribute('email', 'john', '*****@*****.**') add_attribute('wtf', 'john', lasso.MiscTextNode.newWithXmlNode('<a>coucou</a>')) if not auth_result and msg: login.response.status.statusMessage = msg if login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_ART: login.buildArtifactMsg(lasso.HTTP_METHOD_ARTIFACT_GET) self.artifact = login.artifact self.artifact_message = login.artifactMessage elif login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_POST: login.buildAuthnResponseMsg() else: raise NotImplementedError if login.msgBody: assert b'rsa-sha256' in base64.b64decode(login.msgBody) return login.msgUrl, login.msgBody, login.msgRelayState