def do_POST(self): """Serve a POST request.""" if not self.path == self.saml_post_path: self._bad_request() return length = int(self.headers['Content-Length']) data = self.rfile.read(length) query = urlparse.parse_qs(data) res = Response( query['SAMLResponse'].pop(), self.settings['idp_cert_fingerprint'], ) valid = res.is_valid() name_id = res.name_id if valid: msg = 'The identity of {name_id} has been verified'.format( name_id=name_id, ) self._serve_msg(200, msg) else: msg = '{name_id} is not authorized to use this resource'.format( name_id=name_id, ) self._serve_msg(401, msg)
def test_is_valid_simple(self): encoded_response = base64.b64encode(test_response) res = Response( response=encoded_response, signature='foo signature', ) def fake_clock(): return datetime(2004, 12, 05, 9, 18, 45, 462796) fake_verifier = fudge.Fake( 'verifier', callable=True, ) fake_verifier.times_called(1) fake_verifier.with_args(res._document, 'foo signature') fake_verifier.returns(True) msg = res.is_valid( _clock=fake_clock, _verifier=fake_verifier, ) eq(msg, True)
def test_is_valid_timezonedifferent(self): encoded_response = base64.b64encode(test_response) res = Response( response=encoded_response, signature='foo signature', ) def fake_clock(): return datetime(2004, 12, 05, 4, 18, 45, 462796,tzinfo=dateutil.tz.tzstr('EST5EDT')) fake_verifier = fudge.Fake( 'verifier', callable=True, ) fake_verifier.times_called(1) fake_verifier.with_args(res._document, 'foo signature') fake_verifier.returns(True) msg = res.is_valid( _clock=fake_clock, _verifier=fake_verifier, ) eq(msg, True)
def test_is_valid_not_before_missing(self): response = """<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="identifier_2" InResponseTo="identifier_1" Version="2.0" IssueInstant="2004-12-05T09:22:05Z" Destination="https://sp.example.com/SAML2/SSO/POST"> <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="identifier_3" Version="2.0" IssueInstant="2004-12-05T09:22:05Z"> <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">foo signature</ds:Signature> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"> 3f7b3dcf-1674-4ecd-92c8-1544f346baf8 </saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData InResponseTo="identifier_1" Recipient="https://sp.example.com/SAML2/SSO/POST" NotOnOrAfter="2024-12-05T09:27:05Z"/> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotOnOrAfter="2024-12-05T09:27:05Z"> <saml:AudienceRestriction> <saml:Audience>https://sp.example.com/SAML2</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2004-12-05T09:22:00Z" SessionIndex="identifier_3"> <saml:AuthnContext> <saml:AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport </saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> </saml:Assertion> </samlp:Response> """ encoded_response = base64.b64encode(response) res = Response( response=encoded_response, signature='foo signature', ) fake_verifier = fudge.Fake( 'verifier', callable=True, ) fake_verifier.times_called(1) fake_verifier.with_args(res._document, 'foo signature') fake_verifier.returns(True) msg = res.is_valid( _verifier=fake_verifier, ) eq(msg, True)