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
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
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')
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, )
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')
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
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
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
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
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
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
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
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
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)]
def authenticate_refresh_token(self, refresh_token): try: return decode_token(refresh_token) except Exception as e: raise InvalidRequestError('invalid refresh token')