def testEmptyProviderExtraction(self): from pas.plugins.suisseid.tests.utils import MockRequest plugin = self.createPlugin() request = MockRequest() request.form['__ac_suisseid_provider_url'] = '' result = plugin.extractCredentials(request) self.assertEquals(result, {})
def testResponseExtraction(self): from pas.plugins.suisseid.tests.utils import MockRequest plugin = self.createPlugin() plugin.changeConfiguration('', 'http://nohost/', '', '', '', '', '', '/usr/local/bin/xmlsec1', os.path.join(path, 'data', 'metadata.xml')) request = MockRequest() # There has to be an outstanding AuthnRequest request.SESSION['suisseid'] = { '2aaaeb7692471eb4ba00d5546877a7fd' : '' } # Create a SAML2 response response = '%s' % self.createIdpResponse('2aaaeb7692471eb4ba00d5546877a7fd') signed_response = self.sign_response(response) encoded_response = base64.b64encode(signed_response) request.form['SAMLResponse'] = encoded_response request.environ['REQUEST_METHOD'] = 'POST' request.stdin = StringIO(urllib.urlencode({'SAMLResponse' : encoded_response})) creds = plugin.extractCredentials(request) self.assertEquals(creds['login'], '1234-1234-1234-1234')
def testResponseNoOutstandingAuthnRequestExtraction(self): from pas.plugins.suisseid.tests.utils import MockRequest plugin = self.createPlugin() plugin.changeConfiguration('', 'http://nohost/', '', '', '', '', '', xmlsec_binary, os.path.join(path, 'data', 'metadata.xml')) request = MockRequest() # There are no outstanding AuthnRequesta request.SESSION['suisseid'] = {} # Create a SAML2 response response = '%s' % self.createIdpResponse() signed_response = self.sign_response(response) encoded_response = base64.b64encode(signed_response) request.form['SAMLResponse'] = encoded_response request.environ['REQUEST_METHOD'] = 'POST' request.stdin = StringIO(urllib.urlencode({'SAMLResponse' : encoded_response})) creds = plugin.extractCredentials(request) self.assertEquals(creds, None)
def testResponseManipulatedExtraction(self): from pas.plugins.suisseid.tests.utils import MockRequest plugin = self.createPlugin() plugin.changeConfiguration('', 'http://nohost/', '', '', '', '', '', xmlsec_binary, os.path.join(path, 'data', 'metadata.xml')) request = MockRequest() # There has to be an outstanding AuthnRequest request.SESSION['suisseid'] = { '2aaaeb7692471eb4ba00d5546877a7fd' : '' } # Create a SAML2 response response = '%s' % self.createIdpResponse('2aaaeb7692471eb4ba00d5546877a7fd') signed_response = self.sign_response(response) # Response has been manipulated by third party (suisseID number changed). signed_response = signed_response.replace('1234-1234-1234-1234', '1234-1234-1234-1235') encoded_response = base64.b64encode(signed_response) request.form['SAMLResponse'] = encoded_response request.environ['REQUEST_METHOD'] = 'POST' request.stdin = StringIO(urllib.urlencode({'SAMLResponse' : encoded_response})) from saml2.sigver import SignatureError self.assertRaises(SignatureError, plugin.extractCredentials, request)
def testResponseAuthnFailedExtraction(self): from pas.plugins.suisseid.tests.utils import MockRequest plugin = self.createPlugin() plugin.changeConfiguration('', 'http://nohost/', '', '', '', '', '', xmlsec_binary, os.path.join(path, 'data', 'metadata.xml')) request = MockRequest() # There has to be an outstanding AuthnRequest request.SESSION['suisseid'] = { '2aaaeb7692471eb4ba00d5546877a7fd' : '' } # Create a SAML2 response response = self.createIdpResponse('2aaaeb7692471eb4ba00d5546877a7fd') from saml2.samlp import StatusCode, STATUS_AUTHN_FAILED response.status.status_code = StatusCode(value=STATUS_AUTHN_FAILED) response = '%s' % response signed_response = self.sign_response(response) encoded_response = base64.b64encode(signed_response) request.form['SAMLResponse'] = encoded_response request.environ['REQUEST_METHOD'] = 'POST' request.stdin = StringIO(urllib.urlencode({'SAMLResponse' : encoded_response})) creds = plugin.extractCredentials(request) self.assertEquals(creds, None)
def testAuthnRequestExtraction(self): from pas.plugins.suisseid.tests.utils import MockRequest, FormParser from saml2.samlp import authn_request_from_string plugin = self.createPlugin() plugin.changeConfiguration('', 'http://nohost/', '', '', '', '', '', xmlsec_binary, os.path.join(path, 'data', 'metadata.xml')) request = MockRequest() request.form['__ac_suisseid_provider_url'] = 'https://idp.swisssign.net/suisseid/eidp/' result = plugin.extractCredentials(request) # No credentials since that's only the first step self.assertEquals(result, None) response = request.response self.assertEquals(response.status, 200) self.assertEquals(response.headers['Content-type'], 'text/html') parser = FormParser() parser.parse(response.body) saml_request = parser.inputs['SAMLRequest'] decoded_xml = base64.b64decode(saml_request) request = authn_request_from_string(decoded_xml) self.assertEquals(request.destination, 'https://idp.swisssign.net/suisseid/eidp/') self.assertEquals(request.assertion_consumer_service_url, plugin.getConfiguration()['portal_url'])
def testExtendedAuthnRequestExtraction(self): from pas.plugins.suisseid.tests.utils import MockRequest, FormParser from saml2.samlp import authn_request_from_string plugin = self.createPlugin() request = MockRequest() request.form['__ac_suisseid_provider_url'] = 'https://idp.swisssign.net/suisseid/eidp/' # Request three attributes: First Name (required), Last Name (required) and isOver18 (optional) plugin.changeConfiguration('suisseID Test Portal', 'http://nohost/', 'First Name\r\nLast Name', 'isOver18', '', '', '', xmlsec_binary, '') request = MockRequest() request.form['__ac_suisseid_provider_url'] = 'https://idp.swisssign.net/suisseid/eidp/' plugin.extractCredentials(request) parser = FormParser() parser.parse(request.response.body) saml_request = parser.inputs['SAMLRequest'] decoded_xml = base64.b64decode(saml_request) request = authn_request_from_string(decoded_xml) self.assertEquals(request.force_authn, 'true') extenions = request.extensions.extension_elements self.assertEquals(len(extenions), 3) self.assertEquals(extenions[0].attributes['Name'], 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname') self.assertEquals(extenions[0].attributes['{http://www.ech.ch/xmlns/eCH-0113/1}required'], 'true')
def testAuthnRequestSignedExtraction(self): from pas.plugins.suisseid.tests.utils import MockRequest, FormParser from saml2.samlp import authn_request_from_string plugin = self.createPlugin() sp_pem = os.path.join(path, 'data', 'sp.pem') sp_key = os.path.join(path, 'data', 'sp.key') plugin.changeConfiguration('suisseID Test Portal', 'http://nohost/', '', '', '', sp_key, sp_pem, xmlsec_binary, '') request = MockRequest() request.form['__ac_suisseid_provider_url'] = 'https://idp.swisssign.net/suisseid/eidp/' plugin.extractCredentials(request) parser = FormParser() parser.parse(request.response.body) saml_request = parser.inputs['SAMLRequest'] decoded_xml = base64.b64decode(saml_request) request = authn_request_from_string(decoded_xml) self.assertEquals(request.destination, 'https://idp.swisssign.net/suisseid/eidp/') # Verify signature from saml2.sigver import verify_signature verified = verify_signature(xmlsec_binary, decoded_xml, sp_pem, node_name='urn:oasis:names:tc:SAML:2.0:protocol:AuthnRequest', cert_type='pem') self.assertEquals(verified, True)