# HG changeset patch # User ymh # Date 1459942309 -7200 # Node ID b25a1526aec363c02982f2449e24cb6afaeef426 # Parent cefef01ac63fee89055f9f971c8186de8231e30c As Rest framework indicates return None if it should try other authentication methods diff -r cefef01ac63f -r b25a1526aec3 server/src/metaeducation/auth.py --- a/server/src/metaeducation/auth.py Fri Apr 01 15:16:30 2016 +0200 +++ b/server/src/metaeducation/auth.py Wed Apr 06 13:31:49 2016 +0200 @@ -6,79 +6,84 @@ from django.contrib.auth import get_user_model, login from django.contrib.auth.models import Permission from rest_framework.authentication import BaseAuthentication +from rest_framework import exceptions logger = logging.getLogger(__name__) class MtdcOAuth2ClientCredentialsAuthentication(BaseAuthentication): - + def authenticate(self, request): # get token, get username if ("act_as" not in request.GET) and ('HTTP_RENKAN_ACT_AS' not in request.META): - logger.debug("CLIENT CREDENTIAL AUTH: no act_as, not client credentials") - return - else: - external_id = request.GET.get('act_as', request.META.get("HTTP_RENKAN_ACT_AS", "")) - try: + logger.debug("CLIENT CREDENTIAL AUTH: no act_as, not client credentials, trying other authentication methods.") + return None + + external_id = request.GET.get('act_as', request.META.get("HTTP_RENKAN_ACT_AS", "")) + + try: user = get_user_model().objects.get(external_id=external_id) except get_user_model().DoesNotExist: logger.debug("CLIENT CREDENTIAL AUTH: User does not exist, abort") - return + raise exceptions.AuthenticationFailed('CLIENT CREDENTIAL AUTH: User does not exist, abort') + if 'HTTP_AUTHORIZATION' not in request.META: logger.debug("CLIENT CREDENTIAL AUTH: no Authorization header, abort") - return - else: - 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) + raise exceptions.AuthenticationFailed('CLIENT CREDENTIAL AUTH: no Authorization header, abort') + + 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"]) + raise exceptions.AuthenticationFailed("CLIENT CREDENTIAL AUTH: Authorization header format is invalid") + + token = match.group(0) + logger.debug("CLIENT CREDENTIAL AUTH: token is %r", token) + # send token to Oauth server validation_service_url = settings.MTDC_VALIDATE_TOKEN_BASE_URL+token+"?redirect_uri="+parse.quote_plus(settings.MTDC_GED_REDIRECT_URI) 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.warning("CLIENT CREDENTIAL AUTH: Validation service didn't response with 200, there may be a problem") - return - + raise exceptions.AuthenticationFailed("CLIENT CREDENTIAL AUTH: Validation service didn't response with 200, there may be a problem") + try: validate_response_json = json.loads(token_validate_response.text) except json.JSONDecodeError as decode_error: logger.warning("CLIENT CREDENTIAL AUTH: Token validate response was not a JSON!") logger.warning("CLIENT CREDENTIAL AUTH: Tried to decode: %r", decode_error.doc) logger.warning("CLIENT CREDENTIAL AUTH: Error message is %r", decode_error.msg) - return - - + raise exceptions.AuthenticationFailed("CLIENT CREDENTIAL AUTH: Token validate response was not a JSON!") + + # 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_REDIRECT_URI): 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_REDIRECT_URI)) - + 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 + raise exceptions.AuthenticationFailed("CLIENT_CREDENTIAL_AUTH: Token validate response doesn't have an error key!") 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 + raise exceptions.AuthenticationFailed("CLIENT CREDENTIAL AUTH: There was an error validating the token") 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) -