Пример #1
0
    def _verify_redirect_uri(self, areq):
        # MUST NOT contain a fragment

        try:
            _redirect_uri = areq["redirect_uri"]
            part = urlparse.urlparse(_redirect_uri)
            if part.fragment:
                raise ValueError

            match = False
            for registered in self.cdb[areq["client_id"]]["redirect_uris"]:
                if _redirect_uri == registered:
                    match=True
                    break
                elif _redirect_uri.startswith(registered):
                    match=True
                    break
            if not match:
                raise AssertionError
            return None
        except Exception:
            logger.error("Faulty redirect_uri: %s" % areq["redirect_uri"])
            logger.info("Registered redirect_uris: %s" % (
                                self.cdb[areq["client_id"]]["redirect_uris"],))
            response = AuthorizationErrorResponse(error="invalid_request",
                               error_description="Faulty redirect_uri")

            return Response(response.to_json(), content="application/json",
                            status="400 Bad Request")
Пример #2
0
    def _authz_error(self, error, descr=None):

        response = AuthorizationErrorResponse(error=error)
        if descr:
            response["error_description"] = descr

        return Response(response.to_json(), content="application/json",
                        status="400 Bad Request")
Пример #3
0
 def handle_backend_error(self, exception):
     """
     See super class satosa.frontends.base.FrontendModule
     :type exception: satosa.exception.SATOSAError
     :rtype: oic.utils.http_util.Response
     """
     auth_req = self._get_authn_request_from_state(exception.state)
     error_resp = AuthorizationErrorResponse(error="access_denied", error_description=exception.message)
     satosa_logging(logger, logging.DEBUG, exception.message, exception.state)
     return SeeOther(error_resp.request(auth_req["redirect_uri"], should_fragment_encode(auth_req)))
Пример #4
0
 def handle_backend_error(self, exception):
     """
     See super class satosa.frontends.base.FrontendModule
     :type exception: satosa.exception.SATOSAError
     :rtype: oic.utils.http_util.Response
     """
     auth_req = self._get_authn_request_from_state(exception.state)
     error_resp = AuthorizationErrorResponse(error="access_denied", error_description=exception.message)
     satosa_logging(logger, logging.DEBUG, exception.message, exception.state)
     return SeeOther(error_resp.request(auth_req["redirect_uri"], should_fragment_encode(auth_req)))
Пример #5
0
def client_error_message(redirect_uri, error="access_denied",
                         error_description="", state=""):
    """Construct an error response and send in fragment part of redirect_uri.
    :param redirect_uri: redirect_uri of the client
    :param error: OpenID Connect error code
    :param error_description: human readable description of the error
    """
    error_resp = AuthorizationErrorResponse(error=error,
                                            error_description=error_description,
                                            state=state)
    location = error_resp.request(redirect_uri, True)
    raise cherrypy.HTTPRedirect(location)
Пример #6
0
    def to_error_url(self):
        redirect_uri = self.request.get('redirect_uri')
        response_type = self.request.get('response_type')
        if redirect_uri and response_type and self.oauth_error:
            error_resp = AuthorizationErrorResponse(
                error=self.oauth_error,
                error_message=str(self),
                state=self.request.get('state'))
            return error_resp.request(redirect_uri,
                                      should_fragment_encode(self.request))

        return None
Пример #7
0
 def handle_backend_error(self, exception):
     """
     See super class satosa.frontends.base.FrontendModule
     :type exception: satosa.exception.SATOSAError
     :rtype: oic.utils.http_util.Response
     """
     auth_req = self._get_authn_request_from_state(exception.state)
     # If the client sent us a state parameter, we should reflect it back according to the spec
     if 'state' in auth_req:
         error_resp = AuthorizationErrorResponse(error="access_denied",
                                                 error_description=exception.message,
                                                 state=auth_req['state'])
     else:
         error_resp = AuthorizationErrorResponse(error="access_denied",
                                                 error_description=exception.message)
     satosa_logging(logger, logging.DEBUG, exception.message, exception.state)
     return SeeOther(error_resp.request(auth_req["redirect_uri"], should_fragment_encode(auth_req)))
Пример #8
0
    def handle_authn_response(self, context, internal_resp):
        auth_req = self._get_authn_request_from_state(context.state)
        affiliation_attribute = self.converter.from_internal(
            'openid', internal_resp.attributes)['affiliation']
        scope = auth_req['scope']
        matching_affiliation = get_matching_affiliation(
            scope, affiliation_attribute)

        if matching_affiliation:
            return super().handle_authn_response(
                context, internal_resp,
                {'auth_time': internal_resp.auth_info.timestamp})

        auth_error = AuthorizationErrorResponse(error='access_denied')
        del context.state[self.name]
        http_response = auth_error.request(auth_req['redirect_uri'],
                                           should_fragment_encode(auth_req))
        return SeeOther(http_response)
Пример #9
0
    def handle_authn_response(self, context, internal_resp):
        auth_req = self._get_authn_request_from_state(context.state)
        # User might not give us consent to release affiliation
        if 'affiliation' in internal_resp.attributes:
            affiliation_attribute = self.converter.from_internal('openid', internal_resp.attributes)['affiliation']
            scope = auth_req['scope']
            matching_affiliation = get_matching_affiliation(scope, affiliation_attribute)

            if matching_affiliation:
                return super().handle_authn_response(context, internal_resp,
                                                     {'auth_time': internal_resp.auth_info.timestamp,
                                                      'requested_scopes': {'values': scope}})
        # User's affiliation was not released or was not the one requested so return an error
        # If the client sent us a state parameter, we should reflect it back according to the spec
        if 'state' in auth_req:
            auth_error = AuthorizationErrorResponse(error='access_denied', state=auth_req['state'])
        else:
            auth_error = AuthorizationErrorResponse(error='access_denied')
        del context.state[self.name]
        http_response = auth_error.request(auth_req['redirect_uri'], should_fragment_encode(auth_req))
        return SeeOther(http_response)
Пример #10
0
    def handle_authn_response(self, context, internal_resp):
        auth_req = self._get_authn_request_from_state(context.state)
        resp_rp = auth_req.get('client_id')

        # User might not give us consent to release affiliation
        if 'affiliation' in internal_resp.attributes:
            affiliation_attribute = self.converter.from_internal('openid', internal_resp.attributes)['affiliation']
            scope = auth_req['scope']
            matching_affiliation = get_matching_affiliation(scope, affiliation_attribute)

            if matching_affiliation:
                transaction_log(context.state, self.config.get("response_exit_order", 1200),
                        "inacademia_frontend", "response", "exit", "success", resp_rp , '', 'Responding successful validation to RP')

                return super().handle_authn_response(context, internal_resp,
                                                     {'auth_time': parser.parse(internal_resp.auth_info.timestamp).timestamp(),
                                                      'requested_scopes': {'values': scope}})

        # User's affiliation was not released or was not the one requested so return an error
        # If the client sent us a state parameter, we should reflect it back according to the spec
        transaction_log(context.state, self.config.get("response_exit_order", 1210),
                        "inacademia_frontend", "response", "exit", "failed", resp_rp, '',
                        ErrorDescription.REQUESTED_AFFILIATION_MISMATCH[LOG_MSG])

        if 'state' in auth_req:
            auth_error = AuthorizationErrorResponse(error='access_denied', state=auth_req['state'],
                                                    error_description=ErrorDescription.REQUESTED_AFFILIATION_MISMATCH[
                                                        ERROR_DESC])
        else:
            auth_error = AuthorizationErrorResponse(error='access_denied',
                                                    error_description=ErrorDescription.REQUESTED_AFFILIATION_MISMATCH[
                                                        ERROR_DESC])
        del context.state[self.name]
        http_response = auth_error.request(auth_req['redirect_uri'], should_fragment_encode(auth_req))

        return SeeOther(http_response)
Пример #11
0
    def test_handle_backend_error(self, context, frontend):
        redirect_uri = "https://client.example.com"
        areq = AuthorizationRequest(client_id=CLIENT_ID, scope="openid", response_type="id_token",
                                    redirect_uri=redirect_uri)
        context.state[frontend.name] = {"oidc_request": areq.to_urlencoded()}

        # fake an error
        message = "test error"
        error = SATOSAAuthenticationError(context.state, message)
        resp = frontend.handle_backend_error(error)

        assert resp.message.startswith(redirect_uri)
        error_response = AuthorizationErrorResponse().deserialize(urlparse(resp.message).fragment)
        error_response["error"] = "access_denied"
        error_response["error_description"] == message
Пример #12
0
    def test_handle_authn_response_returns_error_access_denied_for_wrong_affiliation(
            self, context, scope_value, affiliation):
        authn_req = AuthorizationRequest(
            scope='openid ' + scope_value,
            client_id='client1',
            redirect_uri='https://client.example.com',
            response_type='id_token')
        context.state[self.frontend.name] = {
            'oidc_request': authn_req.to_urlencoded()
        }
        internal_response = InternalResponse()
        internal_response.attributes['affiliation'] = [affiliation]
        internal_response.user_id = 'user1'

        resp = self.frontend.handle_authn_response(context, internal_response)
        auth_resp = AuthorizationErrorResponse().from_urlencoded(
            urlparse(resp.message).fragment)
        assert auth_resp['error'] == 'access_denied'