예제 #1
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)
     msg = exception.message
     logline = lu.LOG_FMT.format(id=lu.get_session_id(exception.state),
                                 message=msg)
     logger.debug(logline)
     return SeeOther(
         error_resp.request(auth_req["redirect_uri"],
                            should_fragment_encode(auth_req)))
예제 #2
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)
예제 #3
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
예제 #4
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'
예제 #5
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)