Ejemplo n.º 1
0
    def validate_endpoint_request(self):
        """The client constructs the request by including the following
        parameters using the "application/x-www-form-urlencoded" format in
        the HTTP request entity-body:

        token
            REQUIRED.  The token that the client wants to get revoked.

        token_type_hint
            OPTIONAL.  A hint about the type of the token submitted for
            revocation.
        """
        if self.request.body_params:
            params = dict(self.request.body_params)
        else:
            params = dict(self.request.query_params)
        if 'token' not in params:
            raise InvalidRequestError()

        token_type = params.get('token_type_hint')
        if token_type and token_type not in self.SUPPORTED_TOKEN_TYPES:
            raise UnsupportedTokenTypeError()
        token = self.query_token(params['token'], token_type,
                                 self.request.client)
        if not token:
            raise InvalidRequestError()
        self.request.credential = token
Ejemplo n.º 2
0
    def validate_endpoint_request(self):
        """The protected resource calls the introspection endpoint using an HTTP
        ``POST`` request with parameters sent as
        "application/x-www-form-urlencoded" data. The protected resource sends a
        parameter representing the token along with optional parameters
        representing additional context that is known by the protected resource
        to aid the authorization server in its response.

        token
            **REQUIRED**  The string value of the token. For access tokens, this
            is the ``access_token`` value returned from the token endpoint
            defined in OAuth 2.0. For refresh tokens, this is the
            ``refresh_token`` value returned from the token endpoint as defined
            in OAuth 2.0.

        token_type_hint
            **OPTIONAL**  A hint about the type of the token submitted for
            introspection.
        """
        if self.request.body_params:
            params = dict(self.request.body_params)
        else:
            raise InvalidRequestError()

        if 'token' not in params:
            raise InvalidRequestError()

        token_type = params.get('token_type_hint')
        if token_type and token_type not in self.SUPPORTED_TOKEN_TYPES:
            raise UnsupportedTokenTypeError()

        token = self.query_token(params['token'], token_type, self._client)
        if token:
            self._token = token
Ejemplo n.º 3
0
    def validate_nonce(self, required=False):
        nonce = self.request.nonce
        if not nonce:
            if required:
                raise InvalidRequestError('Missing "nonce" in request.')
            return True

        if self.server.execute_hook('exists_nonce', nonce, self.request):
            raise InvalidRequestError('Replay attack')
Ejemplo n.º 4
0
    def validate_authorization_redirect_uri(self, client):
        if not self.redirect_uri:
            raise InvalidRequestError('Missing "redirect_uri" in request.', )

        if not client.check_redirect_uri(self.redirect_uri):
            raise InvalidRequestError(
                'Invalid "redirect_uri" in request.',
                state=self.request.state,
            )
Ejemplo n.º 5
0
def validate_nonce(request, exists_nonce, required=False):
    nonce = request.data.get('nonce')
    if not nonce:
        if required:
            raise InvalidRequestError('Missing "nonce" in request.')
        return True

    if exists_nonce(nonce, request):
        raise InvalidRequestError('Replay attack')
Ejemplo n.º 6
0
 def validate_nonce(self, required=False):
     """
     Override method in authlib to skip adding ``exists_nonce`` hook on server. I
     don't think this needs to exist according to OIDC spec but this stays consistent
     with authlib so here we are
     """
     if required:
         if not self.request.nonce:
             raise InvalidRequestError("Missing `nonce`")
         with flask.current_app.db.session as session:
             code = (session.query(AuthorizationCode).filter_by(
                 nonce=self.request.nonce).first())
             if not code:
                 raise InvalidRequestError("Replay attack")
     return True
Ejemplo n.º 7
0
    def create_token_response(self):
        client = self.request.client
        authorization_code = self.request.credential

        user = self.authenticate_user(authorization_code)
        if not user:
            raise InvalidRequestError('There is no "user" for this code.')

        scope = authorization_code.get_scope()

        query_args = dict(self.request.query_params)
        nonce = self.request.body.get("nonce") or query_args.get("nonce")

        token = self.generate_token(
            client,
            self.GRANT_TYPE,
            user=user,
            scope=scope,
            include_refresh_token=client.has_client_secret(),
            nonce=nonce,
        )

        self.request.user = user
        self.server.save_token(token, self.request)
        token = self.process_token(token, self.request)
        self.delete_authorization_code(authorization_code)
        return 200, token, self.TOKEN_RESPONSE_HEADER
Ejemplo n.º 8
0
    def validate_prompt(self, end_user):
        """
        Override method in authlib to fix behavior with login prompt.
        """
        prompt = getattr(self.request, "prompt", None)
        if not prompt:
            if not end_user:
                self.prompt = "login"
            return self

        if prompt == "none" and not end_user:
            raise LoginRequiredError()

        prompts = prompt.split()
        if "none" in prompts and len(prompts) > 1:
            # If this parameter contains none with any other value,
            # an error is returned
            raise InvalidRequestError('Invalid "prompt" parameter.')
        if "login" in prompts:
            prompt = "login"
        if "consent" in prompts:
            if not end_user:
                raise ConsentRequiredError()
            prompt = "consent"
        elif "select_account" in prompts:
            if not end_user:
                raise AccountSelectionRequiredError()
            prompt = "select_account"

        if prompt:
            self.prompt = prompt

        return self
Ejemplo n.º 9
0
    def validate_prompt(self, end_user):
        prompt = self.request.prompt
        if not prompt:
            if not end_user:
                self.prompt = 'login'
            return self

        if prompt == 'none' and not end_user:
            raise LoginRequiredError()

        prompts = prompt.split()
        if 'none' in prompts and len(prompts) > 1:
            # If this parameter contains none with any other value,
            # an error is returned
            raise InvalidRequestError('Invalid "prompt" parameter.')

        if 'consent' in prompts:
            if end_user:
                self.prompt = 'consent'
            elif 'login' in prompts:
                self.prompt = 'login'
            else:
                raise ConsentRequiredError()
        elif 'select_account' in prompts:
            if end_user:
                self.prompt = 'select_account'
            elif 'login' in prompts:
                self.prompt = 'login'
            else:
                raise AccountSelectionRequiredError()
        elif 'login' in prompts:
            self.prompt = 'login'
        return self
Ejemplo n.º 10
0
    def validate_token_request(self):
        params = self.request.data
        if 'username' not in params:
            raise InvalidRequestError('Missing "username" in request.')
        if 'password' not in params:
            raise InvalidRequestError('Missing "password" in request.')

        user = self.authenticate_user(
            params['username'],
            params['password']
        )
        if not user:
            raise InvalidGrantError(
                'Invalid "username" or "password" in request.',
            )
        self.request.user = user
Ejemplo n.º 11
0
 def validate_token_request(self):
     refresh_token = self.request.data.get('refresh_token')
     if refresh_token is None:
         raise InvalidRequestError('Missing "refresh_token" in request.')
     token = self.authenticate_refresh_token(refresh_token)
     if (token['iss'] != current_app.config['JWT_ISSUER']
             or token['token_use'] != 'refresh'):
         raise InvalidGrantError('invalid refresh_token')
     if token['exp'] < timestamp():
         raise InvalidGrantError('refresh_token is expired')
     self.request.credential = token
Ejemplo n.º 12
0
    def validate_prompt(self, end_user):
        prompt = self.request.prompt
        if not prompt:
            if not end_user:
                self.prompt = 'login'
            return self

        if prompt == 'none' and not end_user:
            raise LoginRequiredError()

        prompts = prompt.split()
        if 'none' in prompts and len(prompts) > 1:
            # If this parameter contains none with any other value,
            # an error is returned
            raise InvalidRequestError('Invalid "prompt" parameter.')

        prompt = _guess_prompt_value(end_user, prompts)
        if prompt:
            self.prompt = prompt
        return self
Ejemplo n.º 13
0
def validate_request_prompt(grant):
    prompt = grant.request.data.get('prompt')
    end_user = grant.request.user
    if not prompt:
        if not end_user:
            grant.prompt = 'login'
        return grant

    if prompt == 'none' and not end_user:
        raise LoginRequiredError()

    prompts = prompt.split()
    if 'none' in prompts and len(prompts) > 1:
        # If this parameter contains none with any other value,
        # an error is returned
        raise InvalidRequestError('Invalid "prompt" parameter.')

    prompt = _guess_prompt_value(end_user, prompts)
    if prompt:
        grant.prompt = prompt
    return grant
Ejemplo n.º 14
0
def create_response_mode_response(redirect_uri, params, response_mode=None):
    if response_mode is None:
        response_mode = 'fragment'

    if response_mode == 'form_post':
        tpl = ('<html><head><title>Authlib</title></head>'
               '<body onload="javascript:document.forms[0].submit()">'
               '<form method="post" action="{}">{}</form></body></html>')
        inputs = ''.join([
            '<input type="hidden" name="{}" value="{}"/>'.format(
                quote_url(k), quote_url(v)) for k, v in params
        ])
        body = tpl.format(quote_url(redirect_uri), inputs)
        return 200, body, [('Content-Type', 'text/html; charset=utf-8')]

    if response_mode == 'query':
        uri = add_params_to_uri(redirect_uri, params, fragment=False)
    elif response_mode == 'fragment':
        uri = add_params_to_uri(redirect_uri, params, fragment=True)
    else:
        raise InvalidRequestError('Invalid "response_mode" value')

    return 302, '', [('Location', uri)]
Ejemplo n.º 15
0
 def authenticate_refresh_token(self, refresh_token):
     try:
         return decode_token(refresh_token)
     except Exception as e:
         raise InvalidRequestError('invalid refresh token')