# HG changeset patch # User durandn # Date 1459503781 -7200 # Node ID 10a8296811797aafdb2f597919bb5f6a8e94f430 # Parent 5fb10e370c614e15407ea053546e10547e7d443f Changes on auth.py: better token extraction and validation, better logging, fix to validate response interpretation + changes to oauth.py to properly test changes to auth.py diff -r 5fb10e370c61 -r 10a829681179 oauth/oauth.py --- a/oauth/oauth.py Thu Mar 31 17:16:22 2016 +0200 +++ b/oauth/oauth.py Fri Apr 01 11:43:01 2016 +0200 @@ -230,13 +230,24 @@ @app.route('/rest/oauth/validate/') def validate_token(token): database_token = Token.query.filter_by(access_token=token).first() - related_client = database_token.client + uris = "" + scopes = "" + if database_token is not None: + related_client = database_token.client + scopes = database_token.scopes + uris = related_client.redirect_uris + if database_token is not None and database_token.access_token == token: + validate_errors = "0" + error_description = "" + else: + validate_errors = "1" + error_description = "token not found in db?" return jsonify( access_token=token, - redirect_uri= related_client.redirect_uris, - error=0, - description= "", - scope=database_token.scopes + redirect_uri= uris, + errors=validate_errors, + description= error_description, + scope=scopes ) @app.route('/ws/resource/', methods=["POST", "PUT"]) diff -r 5fb10e370c61 -r 10a829681179 server/src/metaeducation/auth.py --- a/server/src/metaeducation/auth.py Thu Mar 31 17:16:22 2016 +0200 +++ b/server/src/metaeducation/auth.py Fri Apr 01 11:43:01 2016 +0200 @@ -25,18 +25,52 @@ logger.debug("CLIENT CREDENTIAL AUTH: User does not exist, abort") return if 'HTTP_AUTHORIZATION' not in request.META: - logger.debug("CLIENT CREDENTIAL AUTH: no token, abort") + logger.debug("CLIENT CREDENTIAL AUTH: no Authorization header, abort") return else: - token = re.search("(?<=\s).*", request.META["HTTP_AUTHORIZATION"]).group(0) + match = re.search("(?<=Bearer\s).*", request.META["HTTP_AUTHORIZATION"]) + if match is None or len(match.group(0)) == 0: + logger.debug("CLIENT CREDENTIAL AUTH: Authorization header format is invalid: %r", request.META["HTTP_AUTHORIZATION"]) + return + else: + token = match.group(0) logger.debug("CLIENT CREDENTIAL AUTH: token is %r", token) # send token to Oauth server - token_validate_response = requests.get( - settings.MTDC_VALIDATE_TOKEN_BASE_URL+token+"?redirect_uri="+parse.quote_plus(settings.MTDC_GED_BASE_URL) - ) + validation_service_url = settings.MTDC_VALIDATE_TOKEN_BASE_URL+token+"?redirect_uri="+parse.quote_plus(settings.MTDC_GED_BASE_URL) + logger.debug("CLIENT CREDENTIAL AUTH: Requesting validation service %r", validation_service_url) + token_validate_response = requests.get(validation_service_url) if token_validate_response.status_code != 200: - logger.debug("CLIENT CREDENTIAL AUTH: token validate failed, abort") + logger.warning("CLIENT CREDENTIAL AUTH: Validation service didn't response with 200, there may be a problem") return + validate_response_json = json.loads(token_validate_response.text) + + # Response json validation + if "access_token" not in validate_response_json.keys(): + logger.warning("CLIENT_CREDENTIAL_AUTH: Token validate response doesn't have an access_token key!") + elif validate_response_json["access_token"] != token: + logger.warning("CLIENT_CREDENTIAL_AUTH: Token in response %r is different from token extracted from header %r", validate_response_json["access_token"], token) + + if "redirect_uri" not in validate_response_json.keys(): + logger.warning("CLIENT_CREDENTIAL_AUTH: Token validate response doesn't have a redirect_uri key!") + elif validate_response_json["redirect_uri"] != parse.quote_plus(settings.MTDC_GED_BASE_URL): + logger.warning("CLIENT_CREDENTIAL_AUTH: redirect_uri in response %r is different from redirect_uri transmitted in request %r", validate_response_json["redirect_uri"], parse.quote_plus(settings.MTDC_GED_BASE_URL)) + + if "errors" not in validate_response_json.keys(): + logger.warning("CLIENT_CREDENTIAL_AUTH: Token validate response doesn't have an error key!") + logger.warning("CLIENT_CREDENTIAL_AUTH: Aborting as the errors keys is required to check if token was validated") + logger.warning("CLIENT_CREDENTIAL_AUTH: Response was %r", validate_response_json) + return + elif validate_response_json["errors"] != "0" : + logger.debug("CLIENT CREDENTIAL AUTH: There was an error validating the token: %r", validate_response_json.get("description", "no error description in json response")) + return + + if "description" not in validate_response_json.keys(): + logger.warning("CLIENT_CREDENTIAL_AUTH: Token validate response doesn't have a description key!") + + if "scope" not in validate_response_json.keys(): + logger.warning("CLIENT_CREDENTIAL_AUTH: Token validate response doesn't have a scope key!") + + logger.debug("CLIENT CREDENTIAL AUTH: user %r is authenticated by token %r, auth success", external_id, token) return (user, None)