Esempio n. 1
0
    def test_request_full_signed(self):
        """Test full SAML Request/Response flow, fully signed"""
        http_request = self.factory.get("/")
        http_request.user = get_anonymous_user()

        middleware = SessionMiddleware(dummy_get_response)
        middleware.process_request(http_request)
        http_request.session.save()

        # First create an AuthNRequest
        request_proc = RequestProcessor(self.source, http_request,
                                        "test_state")
        request = request_proc.build_auth_n()

        # To get an assertion we need a parsed request (parsed by provider)
        parsed_request = AuthNRequestParser(self.provider).parse(
            b64encode(request.encode()).decode(), "test_state")
        # Now create a response and convert it to string (provider)
        response_proc = AssertionProcessor(self.provider, http_request,
                                           parsed_request)
        response = response_proc.build_response()

        # Now parse the response (source)
        http_request.POST = QueryDict(mutable=True)
        http_request.POST["SAMLResponse"] = b64encode(
            response.encode()).decode()

        response_parser = ResponseProcessor(self.source)
        response_parser.parse(http_request)
Esempio n. 2
0
    def test_request_id_invalid(self):
        """Test generated AuthNRequest with invalid request ID"""
        http_request = self.factory.get("/")
        http_request.user = get_anonymous_user()

        middleware = SessionMiddleware(dummy_get_response)
        middleware.process_request(http_request)
        http_request.session.save()

        # First create an AuthNRequest
        request_proc = RequestProcessor(self.source, http_request,
                                        "test_state")
        request = request_proc.build_auth_n()

        # change the request ID
        http_request.session[SESSION_REQUEST_ID] = "test"
        http_request.session.save()

        # To get an assertion we need a parsed request (parsed by provider)
        parsed_request = AuthNRequestParser(self.provider).parse(
            b64encode(request.encode()).decode(), "test_state")
        # Now create a response and convert it to string (provider)
        response_proc = AssertionProcessor(self.provider, http_request,
                                           parsed_request)
        response = response_proc.build_response()

        # Now parse the response (source)
        http_request.POST = QueryDict(mutable=True)
        http_request.POST["SAMLResponse"] = b64encode(
            response.encode()).decode()

        response_parser = ResponseProcessor(self.source)

        with self.assertRaises(MismatchedRequestID):
            response_parser.parse(http_request)
Esempio n. 3
0
 def check_saml_request(self) -> Optional[HttpRequest]:
     """Create SAML Response from scratch"""
     LOGGER.debug(
         "handle_saml_no_request: No SAML Request, using IdP-initiated flow."
     )
     auth_n_request = AuthNRequestParser(self.provider).idp_initiated()
     self.request.session[SESSION_KEY_AUTH_N_REQUEST] = auth_n_request
Esempio n. 4
0
    def test_response_schema(self):
        """Test generated AuthNRequest against Schema"""
        http_request = self.factory.get("/")
        http_request.user = get_anonymous_user()

        middleware = SessionMiddleware(dummy_get_response)
        middleware.process_request(http_request)
        http_request.session.save()

        # First create an AuthNRequest
        request_proc = RequestProcessor(self.source, http_request,
                                        "test_state")
        request = request_proc.build_auth_n()

        # To get an assertion we need a parsed request (parsed by provider)
        parsed_request = AuthNRequestParser(self.provider).parse(
            b64encode(request.encode()).decode(), "test_state")
        # Now create a response and convert it to string (provider)
        response_proc = AssertionProcessor(self.provider, http_request,
                                           parsed_request)
        response = response_proc.build_response()

        metadata = etree.fromstring(response)  # nosec

        schema = etree.XMLSchema(
            etree.parse("xml/saml-schema-protocol-2.0.xsd"))
        self.assertTrue(schema.validate(metadata))
    def test_request_attributes_invalid(self):
        """Test full SAML Request/Response flow, fully signed"""
        user = create_test_admin_user()
        http_request = get_request("/", user=user)

        # First create an AuthNRequest
        request_proc = RequestProcessor(self.source, http_request,
                                        "test_state")
        request = request_proc.build_auth_n()

        # Create invalid PropertyMapping
        scope = SAMLPropertyMapping.objects.create(name="test",
                                                   saml_name="test",
                                                   expression="q")
        self.provider.property_mappings.add(scope)

        # To get an assertion we need a parsed request (parsed by provider)
        parsed_request = AuthNRequestParser(self.provider).parse(
            b64encode(request.encode()).decode(), "test_state")
        # Now create a response and convert it to string (provider)
        response_proc = AssertionProcessor(self.provider, http_request,
                                           parsed_request)
        self.assertIn(user.username, response_proc.build_response())

        events = Event.objects.filter(action=EventAction.CONFIGURATION_ERROR, )
        self.assertTrue(events.exists())
        self.assertEqual(
            events.first().context["message"],
            "Failed to evaluate property-mapping: name 'q' is not defined",
        )
    def test_signed_valid(self):
        """Test generated AuthNRequest with valid signature"""
        http_request = get_request("/")

        # First create an AuthNRequest
        request_proc = RequestProcessor(self.source, http_request,
                                        "test_state")
        request = request_proc.build_auth_n()
        # Now we check the ID and signature
        parsed_request = AuthNRequestParser(self.provider).parse(
            b64encode(request.encode()).decode(), "test_state")
        self.assertEqual(parsed_request.id, request_proc.request_id)
        self.assertEqual(parsed_request.relay_state, "test_state")
 def test_signed_static(self):
     """Test post request with static request"""
     provider = SAMLProvider(
         name="aws",
         authorization_flow=create_test_flow(),
         acs_url=("https://eu-central-1.signin.aws.amazon.com/platform/"
                  "saml/acs/2d737f96-55fb-4035-953e-5e24134eb778"),
         audience="https://10.120.20.200/saml-sp/SAML2/POST",
         issuer="https://10.120.20.200/saml-sp/SAML2/POST",
         signing_kp=create_test_cert(),
     )
     parsed_request = AuthNRequestParser(provider).parse(POST_REQUEST)
     self.assertEqual(parsed_request.id,
                      "aws_LDxLGeubpc5lx12gxCgS6uPbix1yd5re")
     self.assertEqual(parsed_request.name_id_policy,
                      SAML_NAME_ID_FORMAT_EMAIL)
Esempio n. 8
0
    def test_signed_valid(self):
        """Test generated AuthNRequest with valid signature"""
        http_request = self.factory.get("/")

        middleware = SessionMiddleware(dummy_get_response)
        middleware.process_request(http_request)
        http_request.session.save()

        # First create an AuthNRequest
        request_proc = RequestProcessor(self.source, http_request,
                                        "test_state")
        request = request_proc.build_auth_n()
        # Now we check the ID and signature
        parsed_request = AuthNRequestParser(self.provider).parse(
            b64encode(request.encode()).decode(), "test_state")
        self.assertEqual(parsed_request.id, request_proc.request_id)
        self.assertEqual(parsed_request.relay_state, "test_state")
Esempio n. 9
0
    def check_saml_request(self) -> Optional[HttpRequest]:
        """Handle POST bindings"""
        if REQUEST_KEY_SAML_REQUEST not in self.request.POST:
            LOGGER.info("check_saml_request: SAML payload missing")
            return bad_request_message(self.request,
                                       "The SAML request payload is missing.")

        try:
            auth_n_request = AuthNRequestParser(self.provider).parse(
                self.request.POST[REQUEST_KEY_SAML_REQUEST],
                self.request.POST.get(REQUEST_KEY_RELAY_STATE),
            )
            self.request.session[SESSION_KEY_AUTH_N_REQUEST] = auth_n_request
        except CannotHandleAssertion as exc:
            LOGGER.info(str(exc))
            return bad_request_message(self.request, str(exc))
        return None
Esempio n. 10
0
    def test_request_attributes(self):
        """Test full SAML Request/Response flow, fully signed"""
        user = create_test_admin_user()
        http_request = get_request("/", user=user)

        # First create an AuthNRequest
        request_proc = RequestProcessor(self.source, http_request,
                                        "test_state")
        request = request_proc.build_auth_n()

        # To get an assertion we need a parsed request (parsed by provider)
        parsed_request = AuthNRequestParser(self.provider).parse(
            b64encode(request.encode()).decode(), "test_state")
        # Now create a response and convert it to string (provider)
        response_proc = AssertionProcessor(self.provider, http_request,
                                           parsed_request)
        self.assertIn(user.username, response_proc.build_response())
Esempio n. 11
0
    def test_signed_valid_detached(self):
        """Test generated AuthNRequest with valid signature (detached)"""
        http_request = get_request("/")

        # First create an AuthNRequest
        request_proc = RequestProcessor(self.source, http_request,
                                        "test_state")
        params = request_proc.build_auth_n_detached()
        # Now we check the ID and signature
        parsed_request = AuthNRequestParser(self.provider).parse_detached(
            params["SAMLRequest"],
            params["RelayState"],
            params["Signature"],
            params["SigAlg"],
        )
        self.assertEqual(parsed_request.id, request_proc.request_id)
        self.assertEqual(parsed_request.relay_state, "test_state")
Esempio n. 12
0
 def test_signed_detached_static(self):
     """Test request with detached signature,
     taken from https://www.samltool.com/generic_sso_req.php"""
     static_keypair = CertificateKeyPair.objects.create(
         name="samltool", certificate_data=REDIRECT_CERT)
     provider = SAMLProvider(
         name="samltool",
         authorization_flow=create_test_flow(),
         acs_url="https://10.120.20.200/saml-sp/SAML2/POST",
         audience="https://10.120.20.200/saml-sp/SAML2/POST",
         issuer="https://10.120.20.200/saml-sp/SAML2/POST",
         signing_kp=static_keypair,
         verification_kp=static_keypair,
     )
     parsed_request = AuthNRequestParser(provider).parse_detached(
         REDIRECT_REQUEST, REDIRECT_RELAY_STATE, REDIRECT_SIGNATURE,
         REDIRECT_SIG_ALG)
     self.assertEqual(parsed_request.id,
                      "_dcf55fcd27a887e60a7ef9ee6fd3adab")
     self.assertEqual(parsed_request.name_id_policy,
                      SAML_NAME_ID_FORMAT_UNSPECIFIED)
     self.assertEqual(parsed_request.relay_state, REDIRECT_RELAY_STATE)
Esempio n. 13
0
    def check_saml_request(self) -> Optional[HttpRequest]:
        """Handle POST bindings"""
        payload = self.request.POST
        # Restore the post body from the session
        # This happens when using POST bindings but the user isn't logged in
        # (user gets redirected and POST body is 'lost')
        if SESSION_KEY_POST in self.request.session:
            payload = self.request.session.pop(SESSION_KEY_POST)
        if REQUEST_KEY_SAML_REQUEST not in payload:
            LOGGER.info("check_saml_request: SAML payload missing")
            return bad_request_message(self.request,
                                       "The SAML request payload is missing.")

        try:
            auth_n_request = AuthNRequestParser(self.provider).parse(
                payload[REQUEST_KEY_SAML_REQUEST],
                payload.get(REQUEST_KEY_RELAY_STATE),
            )
            self.request.session[SESSION_KEY_AUTH_N_REQUEST] = auth_n_request
        except CannotHandleAssertion as exc:
            LOGGER.info(str(exc))
            return bad_request_message(self.request, str(exc))
        return None
Esempio n. 14
0
    def check_saml_request(self) -> Optional[HttpRequest]:
        """Handle REDIRECT bindings"""
        if REQUEST_KEY_SAML_REQUEST not in self.request.GET:
            LOGGER.info("handle_saml_request: SAML payload missing")
            return bad_request_message(self.request,
                                       "The SAML request payload is missing.")

        try:
            auth_n_request = AuthNRequestParser(self.provider).parse_detached(
                self.request.GET[REQUEST_KEY_SAML_REQUEST],
                self.request.GET.get(REQUEST_KEY_RELAY_STATE),
                self.request.GET.get(REQUEST_KEY_SAML_SIGNATURE),
                self.request.GET.get(REQUEST_KEY_SAML_SIG_ALG),
            )
            self.request.session[SESSION_KEY_AUTH_N_REQUEST] = auth_n_request
        except CannotHandleAssertion as exc:
            Event.new(
                EventAction.CONFIGURATION_ERROR,
                provider=self.provider,
                message=str(exc),
            ).save()
            LOGGER.info(str(exc))
            return bad_request_message(self.request, str(exc))
        return None