def jwt_decode_handler(token): options = {"verify_exp": api_settings.JWT_VERIFY_EXPIRATION} # get user from token, BEFORE verification, to get user secret key unverified_payload = jwt.decode(token, None, False) secret_key = jwt_get_secret_key(unverified_payload) verified_payload = jwt.decode( token, api_settings.JWT_PUBLIC_KEY or secret_key, api_settings.JWT_VERIFY, options=options, leeway=api_settings.JWT_LEEWAY, audience=api_settings.JWT_AUDIENCE, issuer=api_settings.JWT_ISSUER, algorithms=[api_settings.JWT_ALGORITHM], ) User = get_user_model() # noqa: N806 user = User.objects.get(pk=verified_payload.get("id")) user_issued_at = timegm(user.issued_at.utctimetuple()) if verified_payload.get('orig_iat') < user_issued_at: raise InvalidTokenError() try: if isinstance(token, bytes): token = token.decode() token_denied = user.denied_tokens.get(token=token) if token_denied: raise InvalidTokenError() except DeniedToken.DoesNotExist: return verified_payload
def change_user_email(token: str) -> None: try: jwt_payload = decode_jwt_token(token) except ( ExpiredSignatureError, InvalidSignatureError, DecodeError, InvalidTokenError, ) as error: raise InvalidTokenError() from error if not {"exp", "new_email", "current_email"} <= set(jwt_payload): raise InvalidTokenError() new_email = sanitize_email(jwt_payload["new_email"]) if find_user_by_email(new_email): return current_user = find_user_by_email(jwt_payload["current_email"]) if not current_user: return current_user.email = new_email sessions = UserSession.query.filter_by(userId=current_user.id) repository.delete(*sessions) repository.save(current_user) logger.info("User has changed their email", extra={"user": current_user.id}) return
def change_user_email(token: str) -> None: try: jwt_payload = decode_jwt_token(token) except ( ExpiredSignatureError, InvalidSignatureError, DecodeError, InvalidTokenError, ) as error: raise InvalidTokenError() from error if not {"exp", "new_email", "current_email"} <= set(jwt_payload): raise InvalidTokenError() new_email = jwt_payload["new_email"] if User.query.filter_by(email=new_email).first(): return current_email = jwt_payload["current_email"] current_user = User.query.filter_by(email=current_email).first() if not current_user: return current_user.email = new_email sessions = UserSession.query.filter_by(userId=current_user.id) repository.delete(*sessions) repository.save(current_user) return
def wrapper(*args, **kwargs): mandatory_authorization_type = "Bearer " authorization_header = request.headers.get("Authorization") if authorization_header and mandatory_authorization_type in authorization_header: adage_jwt = authorization_header.replace( mandatory_authorization_type, "") try: adage_jwt_decoded = user_utils.decode_jwt_token_rs256( adage_jwt) except InvalidSignatureError as invalid_signature_error: logger.error("Signature of adage jwt cannot be verified", extra={"error": invalid_signature_error}) raise ForbiddenError({"Authorization": "Unrecognized token"}) except ExpiredSignatureError as expired_signature_error: logger.warning("Token has expired", extra={"error": expired_signature_error}) raise InvalidTokenError("Token expired") if not adage_jwt_decoded.get("exp"): logger.warning("Token does not contain an expiration date") raise InvalidTokenError("No expiration date provided") authenticated_information = AuthenticatedInformation( civility=adage_jwt_decoded.get("civilite"), lastname=adage_jwt_decoded.get("nom"), firstname=adage_jwt_decoded.get("prenom"), email=adage_jwt_decoded.get("mail"), uai=adage_jwt_decoded.get("uai"), ) kwargs["authenticated_information"] = authenticated_information return route_function(*args, **kwargs) raise ForbiddenError({"Authorization": "Unrecognized token"})
def get_jwk_from_jwt(self, unverified_header): try: token_kid = unverified_header["kid"] except KeyError: raise InvalidTokenError("Key ID header parameter is missing") for jwk in self.jwk_set["keys"]: if jwk["kid"] == token_kid: return jwk raise InvalidTokenError("no key found")
async def _jwt_access_token_decode(token): try: decoded = jwt_decode(token.encode(), **jwe_settings) return {"expires": decoded.get("expires"), "session_id": decoded.get("session_id")} except DecodeError as e: log.error(e) raise InvalidTokenError("Invalid token")
def test_removes_invalid_tokens(self): error = InvalidTokenError() self.mock_jwt_decode.side_effect = error self.assertEqual(DukeDSAPIToken.objects.count(), 1, 'Should have one token in database') remove_invalid_dukeds_tokens(self.user) self.assertTrue(self.mock_jwt_decode.called, 'Should call jwt decode') self.assertEqual(DukeDSAPIToken.objects.count(), 0, 'Should have removed token')
def test_fails_bad_token(self): error = InvalidTokenError() self.mock_jwt_decode.side_effect = error authenticated_user = self.dukeds_backend.authenticate(self.key) self.assertIsNone(authenticated_user, 'Should not authenticate user with bad token') self.assertTrue(self.mock_jwt_decode.called, 'Should call jwt decode') self.assertEqual(self.dukeds_backend.failure_reason, error, 'should fail because of our invalid token error')
def decode_jwt(self, authorization_header, verify: typing.Optional[bool] = True): if not authorization_header: raise InvalidTokenError('Authorization headers is missing') logger.debug('found authorization header: ' + str(authorization_header)) jwt_token = authorization_header.replace('Bearer ', '') public_key = self.get_public_key() logger.debug('got public key' + str(public_key)) decoded = self.__get_jwt_data(jwt_token, verify, public_key) logger.info('jwt was decoded successfully') logger.debug('JWT value - ' + str(decoded)) return decoded
def verify_token(cls, token, verify_exp=True): if verify_exp: options = None else: options = {'verify_exp': False} try: payload = jwt.decode(token, current_app.secret_key, verify=True, algorithms=['HS512'], options=options, require_exp=True) except jwt.InvalidTokenError as e: raise InvalidTokenError(403, str(e)) if any(('is_admin' not in payload, 'refresh_exp' not in payload, 'uid' not in payload)): raise InvalidTokenError(403, 'invalid token') # 如果刷新时间过期,则认为 token 无效 if payload['refresh_exp'] < timegm(datetime.utcnow().utctimetuple()): raise InvalidTokenError(403, 'invalid token') u = User.query.get(payload.get('uid')) if u is None: raise InvalidTokenError(403, 'user not exist') return u
def decode_auth_token(token): """ Decode an authentication token provided by JWT :param token: The string/bytes token object :return: The user associated and related payload """ try: payload = jwt.decode(token.encode(), app.config.get("SECRET_KEY")) user = User.query.filter(User.email == payload["sub"]).first() if not user: raise InvalidTokenError() return user, payload except jwt.ExpiredSignatureError: raise Unauthorized("This token has expired") except jwt.InvalidTokenError: traceback.print_exc() raise Unauthorized("Unable to authenticate with that information")
def _get_claims(self, request, obj=None): # pylint: disable=too-many-return-statements """Get JWT claims""" if self.http_header == 'Authorization': # pylint: disable=comparison-with-callable try: if request.authorization is None: return {} except (ValueError, AttributeError): # invalid authorization header return {} (auth_type, token) = request.authorization if auth_type != self.auth_type: # pylint: disable=comparison-with-callable return {} else: token = request.headers.get(self.http_header) if not token: return {} try: configuration = self.configuration # pylint: disable=no-member algorithm = configuration.algorithm if configuration is not None else 'RS512' if algorithm.startswith('HS'): # pylint: disable=no-member key = configuration.secret if configuration is not None else None else: # RS256/RS512 # pylint: disable=no-member key = configuration.public_key if configuration is not None else None claims = jwt.decode(token, key, algorithms=[algorithm], leeway=self.leeway, audience=self.audience) if obj and obj != claims.get('obj'): raise InvalidTokenError('Bad token object!') return claims except InvalidTokenError as exc: LOGGER.warning('Invalid JWT token from %s: %s', getattr(request, 'remote_addr', '--'), exc) return {}