コード例 #1
0
 def test_Saml_handle_logout_request(self):
     not_on_or_after = time.time() + 3600
     identity = {
         'id-1': {
             'https://sso.example.com/idp/metadata': (not_on_or_after, {
                 'authn_info': [],
                 'name_id': 'id-1',
                 'not_on_or_after': not_on_or_after,
                 'came_from': '/next',
                 'ava': {
                     'uid': ['123456']
                 }
             })
         }
     }
     state = {
         'entity_ids': ['https://sso.example.com/idp/metadata'],
         'subject_id': 'id-1',
         'return_to': '/next'
     }
     # modifying config in this test, make copy so as not to effect
     # following tests.
     tmp_sp_config = copy.deepcopy(sp_config)
     # create a response to assert upon
     sp = auth.Saml(tmp_sp_config)
     logout_request = create_logout_request(
         'id-1',
         destination='https://foo.example.com/sp/slo',
         issuer_entity_id='https://sso.example.com/idp/metadata',
         req_entity_id='https://sso.example.com/idp/metadata')
     # test SAMLRequest logout
     with self.app.test_request_context(
             '/',
             method='GET',
             query_string=dict(
                 SAMLRequest=deflate_and_base64_encode(str(logout_request)),
                 RelayState=deflate_and_base64_encode(logout_request.id))):
         # first need to be logged in, let's pretend
         session['_saml_identity'] = identity
         session['_saml_subject_id'] = 'id-1'
         session['_saml_state'] = {logout_request.id: state}
         success, resp = sp.handle_logout(request, next_url='/next')
         self.assertTrue(success)
         self.assertEqual(resp.status_code, 302)
         self.assert_("SAMLResponse" in resp.headers['Location'])
         url = urlparse.urlparse(resp.headers['Location'])
         params = urlparse.parse_qs(url.query)
         self.assert_('SAMLResponse' in params)
         logout = samlp.logout_response_from_string(
             decode_base64_and_inflate(params['SAMLResponse'][0]))
         self.assertEqual(logout.status.status_code.value,
                          'urn:oasis:names:tc:SAML:2.0:status:Success')
         self.assertEqual(logout.destination,
                          'https://sso.example.com/idp/slo')
コード例 #2
0
ファイル: test_saml.py プロジェクト: dellintosh/flask_pysaml2
 def test_Saml_handle_logout_request(self):
     not_on_or_after = time.time()+3600
     identity = {'id-1': {
         'https://sso.example.com/idp/metadata': (
             not_on_or_after, {
                 'authn_info': [],
                 'name_id': 'id-1',
                 'not_on_or_after': not_on_or_after,
                 'came_from': '/next',
                 'ava': {'uid': ['123456']}
             }
         )
     }}
     state = {
         'entity_ids': ['https://sso.example.com/idp/metadata'],
         'subject_id': 'id-1',
         'return_to': '/next'
     }
     # modifying config in this test, make copy so as not to effect
     # following tests.
     tmp_sp_config = copy.deepcopy(sp_config)
     # create a response to assert upon
     sp = auth.Saml(tmp_sp_config)
     logout_request = create_logout_request('id-1',
         destination='https://foo.example.com/sp/slo',
         issuer_entity_id='https://sso.example.com/idp/metadata',
         req_entity_id='https://sso.example.com/idp/metadata')
     # test SAMLRequest logout
     with self.app.test_request_context('/',
             method='GET',
             query_string=dict(
                 SAMLRequest=deflate_and_base64_encode(str(logout_request)),
                 RelayState=deflate_and_base64_encode(logout_request.id))):
         # first need to be logged in, let's pretend
         session['_saml_identity'] = identity
         session['_saml_subject_id'] = 'id-1'
         session['_saml_state'] = {logout_request.id: state}
         success, resp = sp.handle_logout(request, next_url='/next')
         self.assertTrue(success)
         self.assertEqual(resp.status_code, 302)
         self.assert_("SAMLResponse" in resp.headers['Location'])
         url = urlparse.urlparse(resp.headers['Location'])
         params = urlparse.parse_qs(url.query)
         self.assert_('SAMLResponse' in params)
         logout = samlp.logout_response_from_string(
             decode_base64_and_inflate(params['SAMLResponse'][0]))
         self.assertEqual(logout.status.status_code.value,
             'urn:oasis:names:tc:SAML:2.0:status:Success')
         self.assertEqual(logout.destination, 'https://sso.example.com/idp/slo')
コード例 #3
0
ファイル: __init__.py プロジェクト: daggaz/djangosaml2
    def test_logout_service_global(self):
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )

        self.do_login()

        # now simulate a global logout process initiated by another SP
        subject_id = views._get_subject_id(self.client.session)
        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
        saml_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_9961abbaae6d06d251226cb25e38bf8f468036e57e" Version="2.0" IssueInstant="%s" Destination="http://sp.example.com/saml2/ls/"><saml:Issuer>https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">%s</saml:NameID><samlp:SessionIndex>_1837687b7bc9faad85839dbeb319627889f3021757</samlp:SessionIndex></samlp:LogoutRequest>""" % (
            instant, subject_id.text)

        response = self.client.get(
            reverse('saml2_ls'), {
                'SAMLRequest': deflate_and_base64_encode(saml_request),
            })
        self.assertEqual(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEqual(url.hostname, 'idp.example.com')
        self.assertEqual(url.path,
                         '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = parse_qs(url.query)
        self.assertIn('SAMLResponse', params)
        saml_response = params['SAMLResponse'][0]

        if 'Response xmlns' not in decode_base64_and_inflate(
                saml_response).decode('utf-8'):
            raise Exception('Not a valid Response')
コード例 #4
0
 def test_authn_request_http_redirect_right_signature(self):
     xml_message = generate_authn_request()
     encoded_message = deflate_and_base64_encode(xml_message)
     args = {
         'SAMLRequest': encoded_message,
         'SigAlg': SIG_RSA_SHA256,
     }
     query_string = "&".join([urlencode({k: args[k]})
                        for k in REQ_ORDER if k in args]).encode('ascii')
     pkey = import_rsa_key_from_file(os.path.join(DATA_DIR, 'sp.key'))
     signer = self.idp_server.server.sec.sec_backend.get_signer(SIG_RSA_SHA256, pkey)
     args["Signature"] = base64.b64encode(signer.sign(query_string))
     query_string = urlencode(args)
     self.assertEqual(len(self.idp_server.ticket), 0)
     self.assertEqual(len(self.idp_server.responses), 0)
     response = self.test_client.get(
         '/sso-test?{}'.format(query_string),
         follow_redirects=True
     )
     self.assertEqual(response.status_code, 200)
     response_text = response.get_data(as_text=True)
     self.assertIn(
         '<form class="Form Form--spaced u-margin-bottom-l " name="login" method="post" action="/login">',
         response_text
     )
     self.assertEqual(len(self.idp_server.ticket), 1)
     self.assertEqual(len(self.idp_server.responses), 0)
     key = list(self.idp_server.ticket.keys())[0]
     xmlstr = self.idp_server.ticket[key].xmlstr
     self.assertEqual(xml_message, xmlstr)
コード例 #5
0
ファイル: __init__.py プロジェクト: Gagnavarslan/djangosaml2
    def test_logout_service_global(self):
        settings.SAML_CONFIG = conf.create_conf(sp_host='sp.example.com',
                                                idp_hosts=['idp.example.com'])

        self.do_login()

        # now simulate a global logout process initiated by another SP
        subject_id = views._get_subject_id(self.client.session)
        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
        saml_request = '<samlp:LogoutRequest ID="_9961abbaae6d06d251226cb25e38bf8f468036e57e" Version="2.0" IssueInstant="%s" Destination="http://sp.example.com/saml2/ls/" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">%s</saml:NameID><samlp:SessionIndex>_1837687b7bc9faad85839dbeb319627889f3021757</samlp:SessionIndex></samlp:LogoutRequest>' % (
            instant, subject_id)

        response = self.client.get('/ls/', {
                'SAMLRequest': deflate_and_base64_encode(saml_request),
                })
        self.assertEquals(response.status_code, 302)
        location = response['Location']

        url = urlparse.urlparse(location)
        self.assertEquals(url.hostname, 'idp.example.com')
        self.assertEquals(url.path,
                          '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = urlparse.parse_qs(url.query)
        self.assert_('SAMLResponse' in params)

        saml_response = params['SAMLResponse'][0]
        expected_response = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutResponse Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="_9961abbaae6d06d251226cb25e38bf8f468036e57e" IssueInstant="2010-09-05T09:10:12Z" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>"""
        xml = decode_base64_and_inflate(saml_response)
        self.assertSAMLRequestsEquals(expected_response, xml)
コード例 #6
0
ファイル: binding.py プロジェクト: Wazoku/pysaml2
def http_redirect_message(message, location, relay_state="", 
                            typ="SAMLRequest"):
    """The HTTP Redirect binding defines a mechanism by which SAML protocol 
    messages can be transmitted within URL parameters.
    Messages are encoded for use with this binding using a URL encoding 
    technique, and transmitted using the HTTP GET method. 
    
    The DEFLATE Encoding is used in this function.
    
    :param message: The message
    :param location: Where the message should be posted to
    :param relay_state: for preserving and conveying state information
    :return: A tuple containing header information and a HTML message.
    """
    
    if not isinstance(message, basestring):
        message = "%s" % (message,)
        
    args = {typ: deflate_and_base64_encode(message)}
    
    if relay_state:
        args["RelayState"] = relay_state
        
    login_url = "?".join([location, urllib.urlencode(args)])
    headers = [('Location', login_url)]
    body = [""]
    
    return headers, body
コード例 #7
0
    def test_slo_soap(self):
        soon = time_util.in_a_while(days=1)
        sinfo = {
            "name_id": "foba0001",
            "issuer": "urn:mace:example.com:saml:roland:idp",
            "not_on_or_after" : soon,
            "user": {
                "givenName": "Leo",
                "surName": "Laport",
            }
        }

        sp = client.Saml2Client(config_file="server_conf")
        sp.users.add_information_about_person(sinfo)

        logout_request = sp.construct_logout_request(subject_id = "foba0001",
                    destination = "http://localhost:8088/slo",
                    issuer_entity_id = "urn:mace:example.com:saml:roland:idp",
                    reason = "I'm tired of this")

        _ = s_utils.deflate_and_base64_encode("%s" % (logout_request,))

        saml_soap = make_soap_enveloped_saml_thingy(logout_request)
        idp = Server("idp_soap_conf")
        request = idp.parse_logout_request(saml_soap)
        assert request
コード例 #8
0
    def test_logout_service_startingIDP(self):
        self.config.testing_securitypolicy(userid='*****@*****.**',
                                           permissive=True)
        self.set_user_cookie('*****@*****.**')

        came_from = '/afterlogin/'

        session_id = self.add_outstanding_query(came_from)

        saml_response = auth_response(session_id, "hubba-bubba@test")

        # Log in through IDP SAMLResponse
        res = self.testapp.post('/saml2/acs/', params={
            'SAMLResponse': base64.b64encode(saml_response),
            'RelayState': came_from,
        })

        res = self.testapp.get('/saml2/ls/', params={
            'SAMLRequest': deflate_and_base64_encode(
                logout_request(session_id)
            ),
            'RelayState': 'testing-relay-state',
        })

        self.assertEqual(res.status, '302 Found')
        self.assertIn('https://idp.example.com/simplesaml/saml2/idp/'
                      'SingleLogoutService.php?SAMLResponse=', res.location)
        # Set a expired cookie (just the logout header)
        self.assertIn('auth_tkt=""; Path=/; Domain=localhost; Max-Age=0; '
                      'Expires=Wed, 31-Dec-97 23:59:59 GMT',
                      res.headers.getall('Set-Cookie'))
コード例 #9
0
ファイル: pack.py プロジェクト: gusthavosouza/pysaml2-3
def http_redirect_message(message, location, relay_state="", typ="SAMLRequest",
                          sigalg=None, key=None):
    """The HTTP Redirect binding defines a mechanism by which SAML protocol 
    messages can be transmitted within URL parameters.
    Messages are encoded for use with this binding using a URL encoding 
    technique, and transmitted using the HTTP GET method. 
    
    The DEFLATE Encoding is used in this function.
    
    :param message: The message
    :param location: Where the message should be posted to
    :param relay_state: for preserving and conveying state information
    :param typ: What type of message it is SAMLRequest/SAMLResponse/SAMLart
    :param sigalg: The signature algorithm to use.
    :param key: Key to use for signing
    :return: A tuple containing header information and a HTML message.
    """
    
    if not isinstance(message, str):
        message = "%s" % (message,)

    _order = None
    if typ in ["SAMLRequest", "SAMLResponse"]:
        if typ == "SAMLRequest":
            _order = REQ_ORDER
        else:
            _order = RESP_ORDER
        args = {typ: deflate_and_base64_encode(message)}
    elif typ == "SAMLart":
        args = {typ: message}
    else:
        raise Exception("Unknown message type: %s" % typ)

    if relay_state:
        args["RelayState"] = relay_state

    if sigalg:
        # sigalgs
        # http://www.w3.org/2000/09/xmldsig#dsa-sha1
        # http://www.w3.org/2000/09/xmldsig#rsa-sha1

        args["SigAlg"] = sigalg

        try:
            signer = SIGNER_ALGS[sigalg]
        except:
            raise Unsupported("Signing algorithm")
        else:
            string = "&".join([urllib.parse.urlencode({k: args[k]}) for k in _order if k in args])
            args["Signature"] = base64.b64encode(signer.sign(string, key))
            string = urllib.parse.urlencode(args)
    else:
        string = urllib.parse.urlencode(args)

    glue_char = "&" if urllib.parse.urlparse(location).query else "?"
    login_url = glue_char.join([location, string])
    headers = [('Location', str(login_url))]
    body = []
    
    return {"headers": headers, "data": body}
コード例 #10
0
    def test_logout_service_global(self):
        settings.SAML_CONFIG = conf.create_conf(sp_host='sp.example.com',
                                                idp_hosts=['idp.example.com'])

        self.do_login()

        # now simulate a global logout process initiated by another SP
        subject_id = views._get_subject_id(self.client.session)
        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
        saml_request = '<samlp:LogoutRequest ID="_9961abbaae6d06d251226cb25e38bf8f468036e57e" Version="2.0" IssueInstant="%s" Destination="http://sp.example.com/saml2/ls/" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">%s</saml:NameID><samlp:SessionIndex>_1837687b7bc9faad85839dbeb319627889f3021757</samlp:SessionIndex></samlp:LogoutRequest>' % (
            instant, subject_id)

        response = self.client.get(
            '/ls/', {
                'SAMLRequest': deflate_and_base64_encode(saml_request),
            })
        self.assertEquals(response.status_code, 302)
        location = response['Location']

        url = urlparse.urlparse(location)
        self.assertEquals(url.hostname, 'idp.example.com')
        self.assertEquals(url.path,
                          '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = urlparse.parse_qs(url.query)
        self.assert_('SAMLResponse' in params)

        saml_response = params['SAMLResponse'][0]
        expected_response = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutResponse Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="_9961abbaae6d06d251226cb25e38bf8f468036e57e" IssueInstant="2010-09-05T09:10:12Z" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>"""
        xml = decode_base64_and_inflate(saml_response)
        self.assertSAMLRequestsEquals(expected_response, xml)
コード例 #11
0
    def test_authn_response_with_encrypted_assertion(self, sp_conf, context):
        with open(os.path.join(TEST_RESOURCE_BASE_PATH,
                               "idp_metadata_for_encrypted_signed_auth_response.xml")) as idp_metadata_file:
            sp_conf["metadata"]["inline"] = [idp_metadata_file.read()]
        samlbackend = SAMLBackend(Mock(), INTERNAL_ATTRIBUTES, {"sp_config": sp_conf,
                                                                "disco_srv": DISCOSRV_URL},
                                  "base_url", "samlbackend")
        response_binding = BINDING_HTTP_REDIRECT
        relay_state = "test relay state"

        with open(os.path.join(TEST_RESOURCE_BASE_PATH,
                               "auth_response_with_encrypted_signed_assertion.xml")) as auth_response_file:
            auth_response = auth_response_file.read()
        context.request = {"SAMLResponse": deflate_and_base64_encode(auth_response), "RelayState": relay_state}

        context.state[self.samlbackend.name] = {"relay_state": relay_state}
        with open(os.path.join(TEST_RESOURCE_BASE_PATH, "encryption_key.pem")) as encryption_key_file:
            samlbackend.encryption_keys = [encryption_key_file.read()]

        assertion_issued_at = 1479315212
        with patch('saml2.validate.time_util.shift_time') as mock_shift_time, \
                patch('saml2.validate.time_util.utc_now') as mock_utc_now:
            mock_utc_now.return_value = assertion_issued_at + 1
            mock_shift_time.side_effect = [datetime.utcfromtimestamp(assertion_issued_at + 1),
                                     datetime.utcfromtimestamp(assertion_issued_at - 1)]
            samlbackend.authn_response(context, response_binding)

        context, internal_resp = samlbackend.auth_callback_func.call_args[0]
        assert Counter(internal_resp.attributes.keys()) == Counter({"mail", "givenname", "displayname", "surname"})
コード例 #12
0
ファイル: test_samlidp.py プロジェクト: uktrade/staff-sso
def saml_request(**kwargs):
    details = {
        "issue_instant":
        datetime.datetime.now().isoformat("T", "seconds") + "Z",
        "issuer": "http://testsp/saml2/metadata/",
        "entity_id": "http://localhost:8000",
        "destination": "http://localhost:8000/idp/sso/redirect",
        "acs_url": "https://testing.com/saml2/acs/",
        "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
        "name_id_format":
        "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
    }

    details.update(**kwargs)

    saml_request = """<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
            xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
            ID="_f50197d87df55f22010d8b1e1f4de4cb56396cd6ff"
            Version="2.0"
            IssueInstant="{issue_instant}"
            Destination="{destination}"
            AssertionConsumerServiceURL="{acs_url}"
            ProtocolBinding="{binding}">
<saml:Issuer>{issuer}</saml:Issuer>
<samlp:NameIDPolicy Format="{name_id_format}"
              AllowCreate="true" /></samlp:AuthnRequest>""".format(
        **details).encode()

    return deflate_and_base64_encode(saml_request).decode()
コード例 #13
0
ファイル: pack.py プロジェクト: datopian/pysaml2
def http_redirect_message(message, location, relay_state="", typ="SAMLRequest"):
    """The HTTP Redirect binding defines a mechanism by which SAML protocol 
    messages can be transmitted within URL parameters.
    Messages are encoded for use with this binding using a URL encoding 
    technique, and transmitted using the HTTP GET method. 
    
    The DEFLATE Encoding is used in this function.
    
    :param message: The message
    :param location: Where the message should be posted to
    :param relay_state: for preserving and conveying state information
    :return: A tuple containing header information and a HTML message.
    """
    
    if not isinstance(message, basestring):
        message = "%s" % (message,)
        
    args = {typ: deflate_and_base64_encode(message)}
    
    if relay_state:
        args["RelayState"] = relay_state

    glue_char = "&" if urlparse.urlparse(location).query else "?"
    login_url = glue_char.join([location, urllib.urlencode(args)])
    headers = [('Location', login_url)]
    body = [""]
    
    return headers, body
コード例 #14
0
ファイル: test_saml2.py プロジェクト: SUNET/SATOSA
    def test_authn_response_with_encrypted_assertion(self, sp_conf, context):
        with open(os.path.join(TEST_RESOURCE_BASE_PATH,
                               "idp_metadata_for_encrypted_signed_auth_response.xml")) as idp_metadata_file:
            sp_conf["metadata"]["inline"] = [idp_metadata_file.read()]
        samlbackend = SAMLBackend(Mock(), INTERNAL_ATTRIBUTES, {"sp_config": sp_conf,
                                                                "disco_srv": DISCOSRV_URL},
                                  "base_url", "samlbackend")
        response_binding = BINDING_HTTP_REDIRECT
        relay_state = "test relay state"

        with open(os.path.join(TEST_RESOURCE_BASE_PATH,
                               "auth_response_with_encrypted_signed_assertion.xml")) as auth_response_file:
            auth_response = auth_response_file.read()
        context.request = {"SAMLResponse": deflate_and_base64_encode(auth_response), "RelayState": relay_state}

        context.state[self.samlbackend.name] = {"relay_state": relay_state}
        with open(os.path.join(TEST_RESOURCE_BASE_PATH, "encryption_key.pem")) as encryption_key_file:
            samlbackend.encryption_keys = [encryption_key_file.read()]

        assertion_issued_at = 1479315212
        with patch('saml2.validate.time_util.shift_time') as mock_shift_time, \
                patch('saml2.validate.time_util.utc_now') as mock_utc_now:
            mock_utc_now.return_value = assertion_issued_at + 1
            mock_shift_time.side_effect = [datetime.utcfromtimestamp(assertion_issued_at + 1),
                                     datetime.utcfromtimestamp(assertion_issued_at - 1)]
            samlbackend.authn_response(context, response_binding)

        context, internal_resp = samlbackend.auth_callback_func.call_args[0]
        assert Counter(internal_resp.attributes.keys()) == Counter({"mail", "givenname", "displayname", "surname"})
コード例 #15
0
ファイル: test_saml.py プロジェクト: dellintosh/flask_pysaml2
 def test_Saml_handle_logout_response(self):
     not_on_or_after = time.time()+3600
     identity = {'id-1': {
         'https://sso.example.com/idp/metadata': (
             not_on_or_after, {
                 'authn_info': [],
                 'name_id': 'id-1',
                 'not_on_or_after': not_on_or_after,
                 'came_from': '/next',
                 'ava': {'uid': ['123456']}
             }
         )
     }}
     state = {
         'entity_ids': ['https://sso.example.com/idp/metadata'],
         'subject_id': 'id-1',
         'return_to': '/next'
     }
     # modifying config in this test, make copy so as not to effect
     # following tests.
     tmp_sp_config = copy.deepcopy(sp_config)
     # create a response to assert upon
     sp = auth.Saml(tmp_sp_config)
     session_id, logout_response = create_logout_response('id-1',
         destination='https://sso.example.com/idp/slo',
         issuer_entity_id='https://sso.example.com/idp/metadata',
         req_entity_id='https://foo.example.com/sp/metadata')
     self.assert_('Signature' in logout_response)
     # test SAMLResponse logout as GET
     with self.app.test_request_context('/',
             method='GET',
             query_string=dict(
                 SAMLResponse=deflate_and_base64_encode(logout_response),
                 RelayState='/next')):
         # first need to be logged in, let's pretend
         session['_saml_identity'] = identity
         session['_saml_subject_id'] = 'id-1'
         session['_saml_state'] = {session_id: state}
         success, resp = sp.handle_logout(request, next_url='/next')
         self.assertTrue(success)
         self.assertEqual(resp.status_code, 302)
         self.assertEqual(resp.headers['Location'], '/next')
     # test SAMLResponse logout as POST
     with self.app.test_request_context('/',
             method='POST',
             data=dict(
                 SAMLResponse=base64.b64encode(logout_response),
                 RelayState='/next')):
         endpoints = tmp_sp_config['service']['sp']['endpoints']
         slo = endpoints['single_logout_service'][0][0]
         endpoints['single_logout_service'] = [(slo, BINDING_HTTP_POST)]
         # first need to be logged in, let's pretend
         session['_saml_identity'] = identity
         session['_saml_subject_id'] = 'id-1'
         session['_saml_state'] = {session_id: state}
         success, resp = sp.handle_logout(request, next_url='/next')
         self.assertTrue(success)
         self.assertEqual(resp.status_code, 302)
         self.assertEqual(resp.headers['Location'], '/next')
コード例 #16
0
def test_inflate_then_deflate():
    txt = """Selma Lagerlöf (1858-1940) was born in Östra Emterwik, Värmland,
    Sweden. She was brought up on Mårbacka, the family estate, which she did 
    not leave until 1881, when she went to a teachers' college at Stockholm"""

    interm = utils.deflate_and_base64_encode(txt)
    bis = utils.decode_base64_and_inflate(interm)
    assert bis == txt
コード例 #17
0
def test_inflate_then_deflate():
    str = """Selma Lagerlöf (1858-1940) was born in Östra Emterwik, Värmland, 
    Sweden. She was brought up on Mårbacka, the family estate, which she did 
    not leave until 1881, when she went to a teachers' college at Stockholm"""

    interm = utils.deflate_and_base64_encode(str)
    bis = utils.decode_base64_and_inflate(interm)
    assert bis == str
コード例 #18
0
ファイル: pack.py プロジェクト: 571451370/devstack_mitaka
def http_redirect_message(message, location, relay_state="", typ="SAMLRequest",
                          sigalg='', signer=None, **kwargs):
    """The HTTP Redirect binding defines a mechanism by which SAML protocol
    messages can be transmitted within URL parameters.
    Messages are encoded for use with this binding using a URL encoding
    technique, and transmitted using the HTTP GET method.

    The DEFLATE Encoding is used in this function.

    :param message: The message
    :param location: Where the message should be posted to
    :param relay_state: for preserving and conveying state information
    :param typ: What type of message it is SAMLRequest/SAMLResponse/SAMLart
    :param sigalg: Which algorithm the signature function will use to sign
        the message
    :param signer: A signature function that can be used to sign the message
    :return: A tuple containing header information and a HTML message.
    """

    if not isinstance(message, six.string_types):
        message = "%s" % (message,)

    _order = None
    if typ in ["SAMLRequest", "SAMLResponse"]:
        if typ == "SAMLRequest":
            _order = REQ_ORDER
        else:
            _order = RESP_ORDER
        args = {typ: deflate_and_base64_encode(message)}
    elif typ == "SAMLart":
        args = {typ: message}
    else:
        raise Exception("Unknown message type: %s" % typ)

    if relay_state:
        args["RelayState"] = relay_state

    if signer:
        # sigalgs, should be one defined in xmldsig
        assert sigalg in [b for a, b in SIG_ALLOWED_ALG]
        args["SigAlg"] = sigalg

        string = "&".join([urlencode({k: args[k]})
                           for k in _order if k in args]).encode('ascii')
        args["Signature"] = base64.b64encode(signer.sign(string))
        string = urlencode(args)
    else:
        string = urlencode(args)

    glue_char = "&" if urlparse(location).query else "?"
    login_url = glue_char.join([location, string])
    headers = [('Location', str(login_url))]
    body = []

    return {"headers": headers, "data": body}
コード例 #19
0
ファイル: pack.py プロジェクト: rohe/pysaml2
def http_redirect_message(message, location, relay_state="", typ="SAMLRequest",
                          sigalg='', signer=None, **kwargs):
    """The HTTP Redirect binding defines a mechanism by which SAML protocol
    messages can be transmitted within URL parameters.
    Messages are encoded for use with this binding using a URL encoding
    technique, and transmitted using the HTTP GET method.

    The DEFLATE Encoding is used in this function.

    :param message: The message
    :param location: Where the message should be posted to
    :param relay_state: for preserving and conveying state information
    :param typ: What type of message it is SAMLRequest/SAMLResponse/SAMLart
    :param sigalg: Which algorithm the signature function will use to sign
        the message
    :param signer: A signature function that can be used to sign the message
    :return: A tuple containing header information and a HTML message.
    """

    if not isinstance(message, six.string_types):
        message = "%s" % (message,)

    _order = None
    if typ in ["SAMLRequest", "SAMLResponse"]:
        if typ == "SAMLRequest":
            _order = REQ_ORDER
        else:
            _order = RESP_ORDER
        args = {typ: deflate_and_base64_encode(message)}
    elif typ == "SAMLart":
        args = {typ: message}
    else:
        raise Exception("Unknown message type: %s" % typ)

    if relay_state:
        args["RelayState"] = relay_state

    if signer:
        # sigalgs, should be one defined in xmldsig
        assert sigalg in [b for a, b in SIG_ALLOWED_ALG]
        args["SigAlg"] = sigalg

        string = "&".join([urlencode({k: args[k]})
                           for k in _order if k in args]).encode('ascii')
        args["Signature"] = base64.b64encode(signer.sign(string))
        string = urlencode(args)
    else:
        string = urlencode(args)

    glue_char = "&" if urlparse(location).query else "?"
    login_url = glue_char.join([location, string])
    headers = [('Location', str(login_url))]
    body = []

    return {"headers": headers, "data": body}
コード例 #20
0
ファイル: test_12_s_utils.py プロジェクト: sil2100/pysaml2
def test_inflate_then_deflate():
    txt = """Selma Lagerlöf (1858-1940) was born in Östra Emterwik, Värmland,
    Sweden. She was brought up on Mårbacka, the family estate, which she did 
    not leave until 1881, when she went to a teachers' college at Stockholm"""
    if not isinstance(txt, six.binary_type):
        txt = txt.encode('utf-8')

    interm = utils.deflate_and_base64_encode(txt)
    bis = utils.decode_base64_and_inflate(interm)
    if not isinstance(bis, six.binary_type):
        bis = bis.encode('utf-8')
    assert bis == txt
コード例 #21
0
    def test_parse_faulty_request(self):
        authn_request = self.client.authn_request(
                            query_id = "id1",
                            destination = "http://www.example.com",
                            service_url = "http://www.example.org",
                            spentityid = "urn:mace:example.com:saml:roland:sp",
                            my_name = "My real name",
                        )

        intermed = s_utils.deflate_and_base64_encode("%s" % authn_request)
        # should raise an error because faulty spentityid
        raises(OtherError, self.server.parse_authn_request, intermed)
コード例 #22
0
 def test_authn_request_http_redirect_bad_signature(self):
     xml_message = generate_authn_request()
     encoded_message = deflate_and_base64_encode(xml_message)
     self.assertEqual(len(self.idp_server.ticket), 0)
     self.assertEqual(len(self.idp_server.responses), 0)
     response = self.test_client.get(
         '/sso-test?SAMLRequest={}&SigAlg={}&Signature=sign'.format(
             quote(encoded_message), quote(SIG_RSA_SHA256)),
         follow_redirects=True)
     self.assertEqual(response.status_code, 200)
     response_text = response.get_data(as_text=True)
     self.assertIn('Verifica della firma del messaggio fallita.',
                   response_text)
     self.assertEqual(len(self.idp_server.ticket), 0)
     self.assertEqual(len(self.idp_server.responses), 0)
コード例 #23
0
ファイル: __init__.py プロジェクト: erickt/djangosaml2
    def test_incomplete_logout(self):
        settings.SAML_CONFIG = conf.create_conf(sp_host='sp.example.com',
                                                idp_hosts=['idp.example.com'])

        # don't do a login

        # now simulate a global logout process initiated by another SP
        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
        saml_request = '<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_9961abbaae6d06d251226cb25e38bf8f468036e57e" Version="2.0" IssueInstant="%s" Destination="http://sp.example.com/saml2/ls/"><saml:Issuer>https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">%s</saml:NameID><samlp:SessionIndex>_1837687b7bc9faad85839dbeb319627889f3021757</samlp:SessionIndex></samlp:LogoutRequest>' % (
            instant, 'invalid-subject-id')

        response = self.client.get('/ls/', {
                'SAMLRequest': deflate_and_base64_encode(saml_request),
                })
        self.assertContains(response, 'Logout error', status_code=200)
コード例 #24
0
ファイル: __init__.py プロジェクト: zhukandrey/djangosaml2
    def test_incomplete_logout(self):
        settings.SAML_CONFIG = conf.create_conf(sp_host='sp.example.com',
                                                idp_hosts=['idp.example.com'])

        # don't do a login

        # now simulate a global logout process initiated by another SP
        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
        saml_request = '<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_9961abbaae6d06d251226cb25e38bf8f468036e57e" Version="2.0" IssueInstant="%s" Destination="http://sp.example.com/saml2/ls/"><saml:Issuer>https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">%s</saml:NameID><samlp:SessionIndex>_1837687b7bc9faad85839dbeb319627889f3021757</samlp:SessionIndex></samlp:LogoutRequest>' % (
            instant, 'invalid-subject-id')

        response = self.client.get(reverse('saml2_ls'), {
            'SAMLRequest': deflate_and_base64_encode(saml_request),
        })
        self.assertContains(response, 'Logout error', status_code=403)
コード例 #25
0
ファイル: __init__.py プロジェクト: Telmediq/djangosaml2
    def test_logout_service_local(self):
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )

        self.do_login()

        response = self.client.get(reverse('saml2_logout'))
        self.assertEquals(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEquals(url.hostname, 'idp.example.com')
        self.assertEquals(url.path,
                          '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = parse_qs(url.query)
        self.assert_('SAMLRequest' in params)

        saml_request = params['SAMLRequest'][0]
        if PY_VERSION < (2, 7):
            expected_request = """<?xml version='1.0' encoing='UTF-8'?>
<samlp:LogoutRequest Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">58bcc81ea14700f66aeb707a0eff1360</saml:NameID></samlp:LogoutRequest>"""
        elif PY_VERSION < (3, ):
            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
        else:
            expected_request = """<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
        self.assertSAMLRequestsEquals(
            decode_base64_and_inflate(saml_request).decode('utf-8'),
            expected_request)

        # now simulate a logout response sent by the idp
        request_id = re.findall(r' ID="(.*?)" ', xml)[0]
        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')

        saml_response = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutResponse xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://sp.example.com/saml2/ls/" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="%s" IssueInstant="%s" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>""" % (
            request_id, instant)

        response = self.client.get(
            reverse('saml2_ls'), {
                'SAMLResponse': deflate_and_base64_encode(saml_response),
            })
        self.assertContains(response, "Logged out", status_code=200)
        self.assertEquals(self.client.session.keys(), [])
コード例 #26
0
    def test_parse_faulty_request_to_err_status(self):
        authn_request = self.client.authn_request(
                            query_id = "id1",
                            destination = "http://www.example.com",
                            service_url = "http://www.example.org",
                            spentityid = "urn:mace:example.com:saml:roland:sp",
                            my_name = "My real name",
                        )

        intermed = s_utils.deflate_and_base64_encode("%s" % authn_request)
        try:
            self.server.parse_authn_request(intermed)
            status = None
        except OtherError, oe:
            print oe.args
            status = s_utils.error_status_factory(oe)
コード例 #27
0
 def test_authn_request_http_redirect_missing_sigalg_and_signature_parameter(
         self):
     # See: https://github.com/italia/spid-testenv2/issues/36
     xml_message = generate_authn_request()
     encoded_message = deflate_and_base64_encode(xml_message)
     self.assertEqual(len(self.idp_server.ticket), 0)
     self.assertEqual(len(self.idp_server.responses), 0)
     response = self.test_client.get('/sso-test?SAMLRequest={}'.format(
         quote(encoded_message), quote(SIG_RSA_SHA256)),
                                     follow_redirects=True)
     self.assertEqual(response.status_code, 200)
     response_text = response.get_data(as_text=True)
     self.assertIn(
         'I parametri Signature e SigAlg sono entrambi necessari per le richieste di tipo HTTP-REDIRECT',
         response_text)
     self.assertEqual(len(self.idp_server.ticket), 0)
     self.assertEqual(len(self.idp_server.responses), 0)
コード例 #28
0
ファイル: __init__.py プロジェクト: liquidpele/djangosaml2
    def test_logout_service_local(self):
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )

        self.do_login()

        response = self.client.get(reverse('saml2_logout'))
        self.assertEquals(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEquals(url.hostname, 'idp.example.com')
        self.assertEquals(url.path,
                          '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = parse_qs(url.query)
        self.assert_('SAMLRequest' in params)

        saml_request = params['SAMLRequest'][0]
        if PY_VERSION < (2, 7):
            expected_request = """<?xml version='1.0' encoing='UTF-8'?>
<samlp:LogoutRequest Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">58bcc81ea14700f66aeb707a0eff1360</saml:NameID></samlp:LogoutRequest>"""
        elif PY_VERSION < (3,):
            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
        else:
            expected_request = """<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
        self.assertSAMLRequestsEquals(decode_base64_and_inflate(saml_request).decode('utf-8'),
                                      expected_request)

        # now simulate a logout response sent by the idp
        request_id = re.findall(r' ID="(.*?)" ', xml)[0]
        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')

        saml_response = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutResponse xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://sp.example.com/saml2/ls/" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="%s" IssueInstant="%s" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>""" % (
            request_id, instant)

        response = self.client.get(reverse('saml2_ls'), {
                'SAMLResponse': deflate_and_base64_encode(saml_response),
                })
        self.assertContains(response, "Logged out", status_code=200)
        self.assertEquals(self.client.session.keys(), [])
コード例 #29
0
    def test_logout_service_startingSP_already_logout(self):

        came_from = '/afterlogin/'
        session_id = self.add_outstanding_query(came_from)

        res = self.testapp.get('/saml2/ls/', params={
            'SAMLResponse': deflate_and_base64_encode(
                logout_response(session_id)
            ),
            'RelayState': 'testing-relay-state',
        })

        self.assertEqual(res.status, '302 Found')
        self.assertIn(self.settings['saml2.logout_redirect_url'], res.location)
        # Set a expired cookie (just the logout header)
        self.assertIn('auth_tkt=""; Path=/; Domain=localhost; Max-Age=0; '
                      'Expires=Wed, 31-Dec-97 23:59:59 GMT',
                      res.headers.getall('Set-Cookie'))
コード例 #30
0
    def test_logout_service_startingSP_already_logout(self):

        came_from = '/afterlogin/'
        session_id = self.add_outstanding_query(came_from)

        with self.app.test_request_context(
                '/saml2-ls',
                method='POST',
                data={
                    'SAMLResponse':
                    deflate_and_base64_encode(logout_response(session_id)),
                    'RelayState':
                    'testing-relay-state',
                }):
            response = self.app.dispatch_request()

            self.assertEqual(response.status, '302 FOUND')
            self.assertIn('testing-relay-state', response.location)
コード例 #31
0
ファイル: __init__.py プロジェクト: mjr9804/djangosaml2
    def test_logout_service_local(self):
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )

        self.do_login()

        response = self.client.get(reverse('saml2_logout'))
        self.assertEqual(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEqual(url.hostname, 'idp.example.com')
        self.assertEqual(url.path,
                         '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = parse_qs(url.query)
        self.assertIn('SAMLRequest', params)

        saml_request = params['SAMLRequest'][0]

        self.assertIn('LogoutRequest xmlns',
                      decode_base64_and_inflate(saml_request).decode('utf-8'),
                      'Not a valid LogoutRequest')

        # now simulate a logout response sent by the idp
        expected_request = """<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="XXXXXXXXXXXXXXXXXXXXXX" Version="2.0" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" Reason=""><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">1f87035b4c1325b296a53d92097e6b3fa36d7e30ee82e3fcb0680d60243c1f03</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""

        request_id = re.findall(r' ID="(.*?)" ', expected_request)[0]
        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')

        saml_response = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutResponse xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://sp.example.com/saml2/ls/" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="%s" IssueInstant="%s" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>""" % (
            request_id, instant)

        response = self.client.get(
            reverse('saml2_ls'), {
                'SAMLResponse': deflate_and_base64_encode(saml_response),
            })
        self.assertContains(response, "Logged out", status_code=200)
        self.assertListEqual(list(self.client.session.keys()), [])
コード例 #32
0
ファイル: test_authn.py プロジェクト: lamlion/eduid-webapp
    def test_logout_service_startingIDP(self):

        eppn = 'hubba-bubba'
        came_from = '/afterlogin/'
        session_id = self.add_outstanding_query(came_from)
        cookie = self.dump_session_cookie(session_id)

        saml_response = auth_response(session_id, eppn).encode('utf-8')

        # Log in through IDP SAMLResponse
        with self.app.test_request_context(
                '/saml2-acs',
                method='POST',
                headers={'Cookie': cookie},
                data={
                    'SAMLResponse': base64.b64encode(saml_response),
                    'RelayState': '/testing-relay-state',
                },
        ):
            self.app.dispatch_request()
            session.persist(
            )  # Explicit session.persist is needed when working within a test_request_context

        with self.app.test_request_context(
                '/saml2-ls',
                method='POST',
                headers={'Cookie': cookie},
                data={
                    'SAMLRequest':
                    deflate_and_base64_encode(logout_request(session_id)),
                    'RelayState':
                    '/testing-relay-state',
                },
        ):
            response = self.app.dispatch_request()

            self.assertEqual(response.status, '302 FOUND')
            self.assertIn(
                'https://idp.example.com/simplesaml/saml2/idp/'
                'SingleLogoutService.php?SAMLResponse=',
                response.location,
            )
コード例 #33
0
    def test_parse_ok_request(self):
        authn_request = self.client.authn_request(
                            query_id = "id1",
                            destination = "http://localhost:8088/sso",
                            service_url = "http://localhost:8087/",
                            spentityid = "urn:mace:example.com:saml:roland:sp",
                            my_name = "My real name",
                        )

        print authn_request
        intermed = s_utils.deflate_and_base64_encode("%s" % authn_request)
        response = self.server.parse_authn_request(intermed)
        # returns a dictionary
        print response
        assert response["consumer_url"] == "http://localhost:8087/"
        assert response["id"] == "id1"
        name_id_policy = response["request"].name_id_policy
        assert _eq(name_id_policy.keyswv(), ["format", "allow_create"])
        assert name_id_policy.format == saml.NAMEID_FORMAT_TRANSIENT
        assert response["sp_entity_id"] == "urn:mace:example.com:saml:roland:sp"
コード例 #34
0
    def test_logout_service_startingIDP_no_subject_id(self):

        eppn = 'hubba-bubba'
        came_from = '/afterlogin/'
        session_id = self.add_outstanding_query(came_from)
        cookie = self.dump_session_cookie(session_id)

        saml_response = auth_response(session_id, eppn)

        # Log in through IDP SAMLResponse
        with self.app.test_request_context('/saml2-acs',
                                           method='POST',
                                           headers={'Cookie': cookie},
                                           data={
                                               'SAMLResponse':
                                               base64.b64encode(saml_response),
                                               'RelayState':
                                               'testing-relay-state',
                                           }):
            response = self.app.dispatch_request()

        with self.app.test_request_context('/saml2-ls',
                                           method='POST',
                                           headers={'Cookie': cookie},
                                           data={
                                               'SAMLRequest':
                                               deflate_and_base64_encode(
                                                   logout_request(session_id)),
                                               'RelayState':
                                               'testing-relay-state',
                                           }):
            del session['_saml2_session_name_id']
            session.persist()
            response = self.app.dispatch_request()

            self.assertEqual(response.status, '302 FOUND')
            self.assertIn('testing-relay-state', response.location)
コード例 #35
0
    def test_slo_http_post(self):
        soon = time_util.in_a_while(days=1)
        sinfo = {
            "name_id": "foba0001",
            "issuer": "urn:mace:example.com:saml:roland:idp",
            "not_on_or_after" : soon,
            "user": {
                "givenName": "Leo",
                "surName": "Laport",
            }
        }
        self.client.users.add_information_about_person(sinfo)

        logout_request = self.client.construct_logout_request(
                    subject_id="foba0001",
                    destination = "http://localhost:8088/slop",
                    issuer_entity_id = "urn:mace:example.com:saml:roland:idp",
                    reason = "I'm tired of this")

        intermed = s_utils.deflate_and_base64_encode("%s" % (logout_request,))

        #saml_soap = make_soap_enveloped_saml_thingy(logout_request)
        request = self.server.parse_logout_request(intermed, BINDING_HTTP_POST)
        assert request
コード例 #36
0
 def _create_idp_logout_request(self):
     """
     enc_resp is an encrypted and base64 encoded logout response
     """
     logout_xml = '<samlp:LogoutRequest  xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="s26bce413ad43ae7ff430a065122b7b16f31e17802" Version="2.0" IssueInstant="2012-05-08T12:46:11Z" Destination="http://nohost/logout" NotOnOrAfter="2012-05-08T12:56:11Z"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://nohost/auth</saml:Issuer><saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" NameQualifier="http://nohost/auth" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">1kFn6vXCTJ7Uo5v572Z1IsaLK8yQ</saml:NameID><samlp:SessionIndex xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">s26997d5ef9cbf708cc46b732624d90bba15cfb101</samlp:SessionIndex></samlp:LogoutRequest>'
     return deflate_and_base64_encode(logout_xml)
コード例 #37
0
from saml2 import config, s_utils
from saml2.server import Server
from saml2.client import Saml2Client

__author__ = 'rolandh'

server = Server("idp_conf")

conf = config.SPConfig()
conf.load_file("server_conf")
client = Saml2Client(conf)

id, authn_request = client.create_authn_request(
    id="id1", destination="http://localhost:8088/sso")

print(authn_request)
intermed = s_utils.deflate_and_base64_encode("%s" % authn_request)

response = server.parse_authn_request(intermed)
コード例 #38
0
ファイル: debug_server.py プロジェクト: lvanderree/pysaml2-3
from saml2 import config, s_utils
from saml2.server import Server
from saml2.client import Saml2Client

__author__ = 'rolandh'

server = Server("idp_conf")

conf = config.SPConfig()
conf.load_file("server_conf")
client = Saml2Client(conf)

id, authn_request = client.create_authn_request(id = "id1",
                                    destination = "http://localhost:8088/sso")

print(authn_request)
intermed = s_utils.deflate_and_base64_encode("%s" % authn_request)

response = server.parse_authn_request(intermed)
コード例 #39
0
 def test_Saml_handle_logout_response(self):
     not_on_or_after = time.time() + 3600
     identity = {
         'id-1': {
             'https://sso.example.com/idp/metadata': (not_on_or_after, {
                 'authn_info': [],
                 'name_id': 'id-1',
                 'not_on_or_after': not_on_or_after,
                 'came_from': '/next',
                 'ava': {
                     'uid': ['123456']
                 }
             })
         }
     }
     state = {
         'entity_ids': ['https://sso.example.com/idp/metadata'],
         'subject_id': 'id-1',
         'return_to': '/next'
     }
     # modifying config in this test, make copy so as not to effect
     # following tests.
     tmp_sp_config = copy.deepcopy(sp_config)
     # create a response to assert upon
     sp = auth.Saml(tmp_sp_config)
     session_id, logout_response = create_logout_response(
         'id-1',
         destination='https://sso.example.com/idp/slo',
         issuer_entity_id='https://sso.example.com/idp/metadata',
         req_entity_id='https://foo.example.com/sp/metadata')
     self.assert_('Signature' in logout_response)
     # test SAMLResponse logout as GET
     with self.app.test_request_context(
             '/',
             method='GET',
             query_string=dict(
                 SAMLResponse=deflate_and_base64_encode(logout_response),
                 RelayState='/next')):
         # first need to be logged in, let's pretend
         session['_saml_identity'] = identity
         session['_saml_subject_id'] = 'id-1'
         session['_saml_state'] = {session_id: state}
         success, resp = sp.handle_logout(request, next_url='/next')
         self.assertTrue(success)
         self.assertEqual(resp.status_code, 302)
         self.assertEqual(resp.headers['Location'], '/next')
     # test SAMLResponse logout as POST
     with self.app.test_request_context(
             '/',
             method='POST',
             data=dict(SAMLResponse=base64.b64encode(logout_response),
                       RelayState='/next')):
         endpoints = tmp_sp_config['service']['sp']['endpoints']
         slo = endpoints['single_logout_service'][0][0]
         endpoints['single_logout_service'] = [(slo, BINDING_HTTP_POST)]
         # first need to be logged in, let's pretend
         session['_saml_identity'] = identity
         session['_saml_subject_id'] = 'id-1'
         session['_saml_state'] = {session_id: state}
         success, resp = sp.handle_logout(request, next_url='/next')
         self.assertTrue(success)
         self.assertEqual(resp.status_code, 302)
         self.assertEqual(resp.headers['Location'], '/next')