Example #1
0
 def _validate_claims(self, claims, options=None):
     if options is None:
         options = self._claims_options
     claims.options = options
     try:
         claims.validate()
     except jwt_errors.ExpiredTokenError as e:
         logger.error(f'Expired token:\n\t{self._compare_claims(claims)}')
         raise AuthenticationError(f"Token is expired {e.args}")
     except jwt_errors.InvalidClaimError as e:
         logger.error(f'Invalid claims:\n\t{self._compare_claims(claims)}')
         raise AuthenticationError(f"Invalid claims {e.args}")
     except jwt_errors.MissingClaimError as e:
         logger.error(f'Missing claims:\n\t{self._compare_claims(claims)}')
         raise AuthenticationError(f"Missing claims {e.args}")
     except Exception as e:
         logger.exception('Unable to parse error')
         raise AuthenticationError(f"Unable to parse authentication token {e.args}")
     return claims
Example #2
0
    async def authenticate(self, request):
        method = request.scope.get('method')
        path = request.scope.get('path')

        if method == 'POST' and path in ['/', '/token', '/user']:
            return

        if "Authorization" not in request.headers:
            raise AuthenticationError('Invalid token.')

        auth = request.headers["Authorization"]
        try:
            token = auth.split('Token')[1].strip()
        except IndexError:
            raise AuthenticationError('Invalid token.')

        user = check_user_token(token)
        user.is_authenticated = True

        return AuthCredentials(["authenticated"]), user
Example #3
0
 def _decode_token(self, token):
     jwk_ = self._get_ms_jwk(token)
     claims = None
     try:
         claims = jwt.decode(
             token,
             jwk_.public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.PKCS1),
         )
     except Exception:
         logger.exception('Unable to parse error')
         raise AuthenticationError("Unable to parse authentication token")
     return claims
Example #4
0
 def _get_ms_jwk(self, token):
     try:
         jwks = requests.get(self.key_url).json()
         token_header = token.split(".")[0].encode()
         unverified_header = extract_header(token_header, jwt_errors.DecodeError)
         for key in jwks["keys"]:
             if key["kid"] == unverified_header["kid"]:
                 logger.info(f'Identified key {key["kid"]}')
                 return jwk.loads(key)
     except jwt_errors.DecodeError:
         logger.exception('Error parsing signing keys')
     raise AuthenticationError("Unable to parse signing keys")
Example #5
0
 def _validate_claims(self, claims, options=None):
     if options is None:
         options = self._claims_options
     # We need to do some 1.0/2.0 handling because it doesn't seem to work properly
     # TODO: validate whether we want this claim here?
     if 'appid' in options and 'azp' in options:
         if 'appid' not in claims:
             options.pop('appid')
         elif 'azp'not in claims:
             options.pop('azp')
         if not ('appid' in claims or 'azp' in claims):
             if self.strict:
                 self.logger.error('No appid/azp claims found in token')
                 raise AuthenticationError('No appid/azp claims found in token')
             else:
                 self.logger.warning('No appid/azp claims found in token - we are ignoring for now')
     return super()._validate_claims(claims, options)
Example #6
0
 def _get_ms_jwk(self, token: str) -> JsonWebKey:
     try:
         self.logger.info(f'Getting signing keys from {self.key_url}')
         token_header = token.split(".")[0].encode()
         jwks = self._request_ms_jwks()
         unverified_header = extract_header(token_header, jwt_errors.DecodeError)
         # Authlib 1.0.0 changed behaviour of loads in 1.0.0
         if version.parse(authlib_version) >= version.parse('1.0.0'):
             # This can now raise a ValueError: Invalid JSON Web Key Set if
             # the key is not found
             return jwk.loads(jwks, unverified_header['kid'])
         else:
             for key in jwks["keys"]:
                 if key["kid"] == unverified_header["kid"]:
                     self.logger.info(f'Identified key {key["kid"]}')
                     return jwk.loads(key)
     except jwt_errors.DecodeError:
         self.logger.exception('Error parsing signing keys')
     except ValueError:
         self.logger.exception('Error finding key')
     raise AuthenticationError("Unable to parse signing keys")
Example #7
0
 def _decode_token(self, token):
     jwk_ = self._get_ms_jwk(token)
     claims = None
     self.logger.debug(f'Key is {jwk_}')
     try:
         if hasattr(jwk_, 'as_pem'):
             # Authlib 1.0.0
             key = jwk_.as_pem()
         elif hasattr(jwk_, 'public_key'):
             # Authlib 1.0.0
             key = jwk_.public_key.public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.PKCS1)
         elif hasattr(jwk_, 'public_bytes'):
             key = jwk_.public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.PKCS1)
         else:
             key = jwk_.raw_key.public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.PKCS1)
         self.logger.debug(f'Processed Key: {key}')
         claims = jwt.decode(
             token,
             key,
         )
     except Exception:
         self.logger.exception('Unable to parse error')
         raise AuthenticationError("Unable to parse authentication token")
     return claims
Example #8
0
def check_user_token(token) -> UserModel:
    try:
        user: UserModel = UserModel.get(UserModel.token == token)
    except UserModel.DoesNotExist:
        raise AuthenticationError('User does not exist.')
    return user