Python jwt.get_unverified_header() Examples

The following are 27 code examples of jwt.get_unverified_header(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module jwt , or try the search function .
Example #1
Source File: jwt-decoder.py    From jwt-pwn with MIT License 6 votes vote down vote up
def main():
    if len(sys.argv) <= 1:
        sys.stdout.write("\t-::: jwt-decoder.py :::-\n")
        sys.stdout.write("# Returns the decoded value  of a JWT.\n")
        sys.stdout.write("\nUsage: %s [jwt-token]\n" % (sys.argv[0]))
        sys.stdout.flush()
        exit(0)

    jwt_token = sys.argv[1]
    jwt_token_header = jwt.get_unverified_header(jwt_token)
    jwt_token_value = jwt.decode(jwt_token, verify=False)
    sys.stdout.write("\n\n")
    sys.stdout.write("[#] JWT Header:\n%s\n\n" %
                     (json.dumps(jwt_token_header)))
    sys.stdout.write("[#] JWT Value:\n%s\n" % (json.dumps(jwt_token_value)))
    sys.stdout.flush()
    exit(0) 
Example #2
Source File: validator.py    From django-cognito-jwt with MIT License 6 votes vote down vote up
def _get_public_key(self, token):
        try:
            headers = jwt.get_unverified_header(token)
        except jwt.DecodeError as exc:
            raise TokenError(str(exc))

        if getattr(settings, "COGNITO_PUBLIC_KEYS_CACHING_ENABLED", False):
            cache_key = "django_cognito_jwt:%s" % headers["kid"]
            jwk_data = cache.get(cache_key)

            if not jwk_data:
                jwk_data = self._json_web_keys.get(headers["kid"])
                timeout = getattr(settings, "COGNITO_PUBLIC_KEYS_CACHING_TIMEOUT", 300)
                cache.set(cache_key, jwk_data, timeout=timeout)
        else:
            jwk_data = self._json_web_keys.get(headers["kid"])

        if jwk_data:
            return RSAAlgorithm.from_jwk(jwk_data) 
Example #3
Source File: auth.py    From clusterfuzz with Apache License 2.0 6 votes vote down vote up
def _validate_iap_jwt(iap_jwt):
  """Validate JWT assertion."""
  project_id = utils.get_application_id()
  expected_audience = '/projects/{}/apps/{}'.format(
      _project_number_from_id(project_id), project_id)

  try:
    key_id = jwt.get_unverified_header(iap_jwt).get('kid')
    if not key_id:
      raise AuthError('No key ID.')

    key = _get_iap_key(key_id)
    decoded_jwt = jwt.decode(
        iap_jwt,
        key,
        algorithms=['ES256'],
        issuer='https://cloud.google.com/iap',
        audience=expected_audience)
    return decoded_jwt['email']
  except (jwt.exceptions.InvalidTokenError,
          requests.exceptions.RequestException) as e:
    raise AuthError('JWT assertion decode error: ' + str(e)) 
Example #4
Source File: __init__.py    From repoxplorer with Apache License 2.0 6 votes vote down vote up
def authorize(self, request, uid=None):
        token = self._get_raw_token(request)
        issuer_info = self._get_issuer_info()
        unverified_headers = jwt.get_unverified_header(token)
        key_id = unverified_headers.get('kid', None)
        if key_id is None:
            raise UnauthorizedException("Missing key id in token")
        jwks_uri = issuer_info.get('jwks_uri')
        if jwks_uri is None:
            raise UnauthorizedException("Missing JWKS URI in config")
        key, algo = self._get_signing_key(jwks_uri, key_id)
        try:
            claims = jwt.decode(token, key, algorithms=algo,
                                issuer=issuer_info['issuer'],
                                audience=self.config['audience'])
        except Exception as e:
            raise UnauthorizedException('Invalid access token: %s' % e)
        if claims['preferred_username'] == self.config.get('admin_username',
                                                           'admin'):
            return 'admin'
        if uid and uid == claims['preferred_username']:
            return uid
        if uid and uid != claims['preferred_username']:
            raise UnauthorizedException("Only the admin ")
        raise UnauthorizedException('unauthorized') 
Example #5
Source File: test_verifier.py    From asap-authentication-python with MIT License 6 votes vote down vote up
def test_verify_jwt_with_none_algorithm(self):
        """ tests that verify_jwt does not accept jwt that use the none
            algorithm.
        """
        verifier = self._setup_jwt_auth_verifier(self._public_key_pem)
        private_key_ret = atlassian_jwt_auth.key.StaticPrivateKeyRetriever(
            self._example_key_id, self._private_key_pem.decode())
        jwt_signer = NoneAlgorithmJwtAuthSigner(
            issuer=self._example_issuer,
            private_key_retriever=private_key_ret,
        )
        for algorithm in ['none', 'None', 'nOne', 'nonE', 'NONE']:
            jwt_token = jwt_signer.generate_jwt(
                self._example_aud, alg_header=algorithm)
            jwt_headers = jwt.get_unverified_header(jwt_token)
            self.assertEqual(jwt_headers['alg'], algorithm)
            with self.assertRaises(jwt.exceptions.InvalidAlgorithmError):
                verifier.verify_jwt(jwt_token, self._example_aud) 
Example #6
Source File: token_verifier.py    From auth0-python with MIT License 6 votes vote down vote up
def verify_signature(self, token):
        try:
            header = jwt.get_unverified_header(token)
        except jwt.exceptions.DecodeError:
            raise TokenValidationError("ID token could not be decoded.")

        alg = header.get('alg', None)
        if alg != self._algorithm:
            raise TokenValidationError(
                'Signature algorithm of "{}" is not supported. Expected the ID token '
                'to be signed with "{}"'.format(alg, self._algorithm))

        kid = header.get('kid', None)
        secret_or_certificate = self._fetch_key(key_id=kid)

        try:
            decoded = jwt.decode(jwt=token, key=secret_or_certificate,
                                 algorithms=[self._algorithm], options=self.DISABLE_JWT_CHECKS)
        except jwt.exceptions.InvalidSignatureError:
            raise TokenValidationError("Invalid token signature.")
        return decoded 
Example #7
Source File: utils.py    From auth0-django-api with MIT License 5 votes vote down vote up
def jwt_decode_token(token):
    header = jwt.get_unverified_header(token)
    auth0_domain = os.environ.get('AUTH0_DOMAIN')
    jwks = requests.get('https://{}/.well-known/jwks.json'.format(auth0_domain)).json()
    public_key = None
    for jwk in jwks['keys']:
        if jwk['kid'] == header['kid']:
            public_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(jwk))

    if public_key is None:
        raise Exception('Public key not found.')

    api_identifier = os.environ.get('API_IDENTIFIER')
    issuer = 'https://{}/'.format(auth0_domain)
    return jwt.decode(token, public_key, audience=api_identifier, issuer=issuer, algorithms=['RS256']) 
Example #8
Source File: metadata.py    From pywarp with Apache License 2.0 5 votes vote down vote up
def metadata_toc(self):
        if self._metadata_toc is None:
            res = requests.get(self.mds_url)
            res.raise_for_status()
            jwt_header = jwt.get_unverified_header(res.content)
            assert jwt_header["alg"] == "ES256"
            cert = x509.load_der_x509_certificate(jwt_header["x5c"][0].encode(),
                                                  cryptography.hazmat.backends.default_backend())
            self._metadata_toc = jwt.decode(res.content, key=cert.public_key(), algorithms=["ES256"])
        return self._metadata_toc 
Example #9
Source File: crackjwt.py    From jwtcrack with GNU Affero General Public License v3.0 5 votes vote down vote up
def signature_is_supported(jwt):
    header = get_unverified_header(jwt)
    return header["alg"] in ["HS256", "HS384", "HS512"] 
Example #10
Source File: crackjwt.py    From jwtcrack with GNU Affero General Public License v3.0 5 votes vote down vote up
def crack_jwt(jwt, dictionary):
    header = get_unverified_header(jwt)
    with open(dictionary) as fp:
        for secret in tqdm(fp):
            secret = secret.rstrip()

            try:
                decode(jwt, secret, algorithms=[header["alg"]])
                return secret
            except DecodeError:
                # Signature verification failed
                pass
            except InvalidTokenError:
                # Signature correct, something else failed
                return secret 
Example #11
Source File: google_auth.py    From timesketch with Apache License 2.0 5 votes vote down vote up
def get_public_key_for_jwt(encoded_jwt, url):
    """Get public key for JWT in order to verify the signature.

    The keys get cached in order to limit the amount of network round trips.

    Args:
        encoded_jwt: Base64 encoded JWT.
        url: URL where keys can be fetched.

    Raises:
        JwTKeyError if keys cannot be fetched.

    Returns:
        Key as string.
    """
    # Get the Key ID from the JWT header.
    key_id = jwt.get_unverified_header(encoded_jwt).get('kid')
    if not key_id:
        raise JwtKeyError('Missing key ID field in token header')
    key_cache = get_public_key_for_jwt.key_cache
    key = key_cache.get(key_id)
    if key:
        return key

    # Re-fetch the key file.
    keys_json = _fetch_public_keys(url)
    if 'keys' in keys_json:
        _new_keys_dict = {}
        for key_dict in keys_json['keys']:
            public_key = jwt.algorithms.RSAAlgorithm.from_jwk(
                json.dumps(key_dict))
            _new_keys_dict[key_dict['kid']] = public_key
        key_cache = _new_keys_dict
    else:
        key_cache = keys_json
    get_public_key_for_jwt.key_cache = key_cache
    key = key_cache.get(key_id)
    if not key:
        raise JwtKeyError('IAP public key {!r} not found'.format(key_id))

    return key 
Example #12
Source File: __init__.py    From quay with Apache License 2.0 5 votes vote down vote up
def _signer_kid(encoded_jwt, allow_none=False):
    headers = get_unverified_header(encoded_jwt)
    kid = headers.get("kid", None)
    if not kid and not allow_none:
        abort(400)

    return kid 
Example #13
Source File: jwtcat.py    From jwtcat with Apache License 2.0 5 votes vote down vote up
def hs256_attack(args):
    """This function passes down different candidates to the run() function and is required
    to handle different types of guessing attack.

    Arguments:
        args {object} -- The command-line arguments
    """
    headers = jwt.get_unverified_header(args.token)

    if not headers['alg'] == "HS256":
        logging.error("JWT signed using an algorithm other than HS256.")
    else:
        tqdm_disable = True if args.log_level == "DEBUG" else False

        if args.attack_mode == "brute-force":
            # Count = ....
            for candidate in tqdm(bruteforce(args.charset, args.increment_min, args.increment_max), disable=tqdm_disable):
                if run(args.token, candidate):
                    return candidate

            return None

        elif args.attack_mode == "wordlist":
            word_count = len(open(args.wordlist.name, "r",
                                  encoding="utf-8").readlines())
            for entry in tqdm(args.wordlist, disable=tqdm_disable, total=word_count):
                if run(args.token, entry.rstrip()):
                    return entry.rstrip()

            return None 
Example #14
Source File: jwtcat.py    From jwtcat with Apache License 2.0 5 votes vote down vote up
def is_vulnerable(args):
    """This function checks a JWT token against a well-known vulnerabilities.

    Arguments:
        args {object} -- The command-line arguments
    """
    headers = jwt.get_unverified_header(args.token)

    if headers['alg'] == "HS256":
        logging.info("JWT vulnerable to HS256 guessing attacks")
    elif headers['alg'] == "None":
        logging.info("JWT vulnerable to CVE-2018-1000531") 
Example #15
Source File: encryptionencoding.py    From chepy with GNU General Public License v3.0 5 votes vote down vote up
def jwt_bruteforce(
        self, wordlist: str, b64_encode: bool = False, algorithm: list = ["HS256"]
    ):
        """Brute force JWT token secret

        This method will use the provided wordlist to try and bruteforce the 
        verification.
        
        Args:
            wordlist (str): Required. Path to a wordlist
            b64_encode (bool, optional): Encoded the words in base64. Defaults to False.
            algorithm (list, optional): Array of valid algorithms. Defaults to ["HS256"].
        
        Returns:
            Chepy: The Chepy object. 
        """
        with open(pathlib.Path(wordlist).expanduser().absolute()) as words:
            for word in words:
                try:
                    word = word.strip()
                    if b64_encode:  # pragma: no cover
                        word = base64.b64encode(word)
                    j = jwt.decode(self._convert_to_str(), word, algorithms=algorithm)
                    self.state = {
                        "paylod": j,
                        "header": jwt.get_unverified_header(self._convert_to_str()),
                        "secret": word,
                    }
                    return self
                except jwt.InvalidSignatureError:
                    continue
            else:  # pragma: no cover
                return self 
Example #16
Source File: encryptionencoding.py    From chepy with GNU General Public License v3.0 5 votes vote down vote up
def jwt_decode(self):
        """Decode a JWT token. Does not verify
        
        Returns:
            Chepy: The Chepy object. 
        """
        self.state = {
            "payload": jwt.decode(self._convert_to_str(), verify=False),
            "header": jwt.get_unverified_header(self._convert_to_str()),
        }
        return self 
Example #17
Source File: key.py    From asap-authentication-python with MIT License 5 votes vote down vote up
def _get_key_id_from_jwt_header(a_jwt):
    """ returns the key identifier from a jwt header. """
    header = jwt.get_unverified_header(a_jwt)
    return KeyIdentifier(header['kid']) 
Example #18
Source File: backends.py    From zulip with Apache License 2.0 5 votes vote down vote up
def decode_id_token(self, id_token: str) -> Dict[str, Any]:
        '''Decode and validate JWT token from Apple and return payload including user data.

        We override this method from upstream python-social-auth, for two reasons:
        * To improve error handling (correctly raising AuthFailed; see comment below).
        * To facilitate this to support the native flow, where
          the Apple-generated id_token is signed for "Bundle ID"
          audience instead of "Services ID".

        It is likely that small upstream tweaks could make it possible
        to make this function a thin wrapper around the upstream
        method; we may want to submit a PR to achieve that.
        '''
        if self.is_native_flow():
            audience = self.setting("BUNDLE_ID")
        else:
            audience = self.setting("SERVICES_ID")

        try:
            kid = jwt.get_unverified_header(id_token).get('kid')
            public_key = RSAAlgorithm.from_jwk(self.get_apple_jwk(kid))
            decoded = jwt.decode(id_token, key=public_key,
                                 audience=audience, algorithm="RS256")
        except PyJWTError:
            # Changed from upstream python-social-auth to raise
            # AuthFailed, which is more appropriate than upstream's
            # AuthCanceled, for this case.
            raise AuthFailed(self, "Token validation failed")

        return decoded 
Example #19
Source File: utils.py    From flask-jwt-extended with MIT License 5 votes vote down vote up
def get_unverified_jwt_headers(encoded_token):
    """
    Returns the Headers of an encoded JWT without verifying the actual signature of JWT.
     Note: The signature is not verified so the header parameters
     should not be fully trusted until signature verification is complete

    :param encoded_token: The encoded JWT to get the Header from.
    :return: JWT header parameters as python dict()
    """
    return jwt.get_unverified_header(encoded_token) 
Example #20
Source File: ocsp_snowflake.py    From snowflake-connector-python with Apache License 2.0 5 votes vote down vote up
def process_key_update_directive(issuer, key_upd_dir_enc):
        """Parses the jwt token as key update directive.

        If the key version in directive < internal key versio do nothing as the internal key is already latest.
        Otherwise update in memory pub key corresponding to the issuer in the directive.

            Expected Format:
            Payload:
            {
                “keyVer” :
                “pubKeyTyp” :
                “pubKey” :
            }
        """
        logger.debug(
            "Received an OCSP Key Update Server Side Directive from Issuer - ",
            issuer)
        jwt_ssd_header = jwt.get_unverified_header(key_upd_dir_enc)
        ssd_issuer = jwt_ssd_header['ssd_iss']

        # Use the in memory public key corresponding to 'issuer'
        # for JWT signature validation.
        jwt_ssd_decoded = jwt.decode(key_upd_dir_enc,
                                     SnowflakeOCSP.SSD.ret_ssd_pub_key(
                                         ssd_issuer), algorithm='RS512')

        ssd_pub_key_ver = float(jwt_ssd_decoded['keyVer'])
        ssd_pub_key_new = jwt_ssd_decoded['pubKey']

        """
        Check for consistency in issuer name
        Check if the key version of the new key is greater than
        existing pub key being used.
        If both checks pass update key.
        """

        if ssd_issuer == issuer and ssd_pub_key_ver > SFSsd.ret_ssd_pub_key_ver(
                ssd_issuer):
            SnowflakeOCSP.SSD.update_pub_key(ssd_issuer, ssd_pub_key_ver,
                                             ssd_pub_key_new) 
Example #21
Source File: ocsp_snowflake.py    From snowflake-connector-python with Apache License 2.0 5 votes vote down vote up
def validate(ssd):
        try:
            ssd_header = jwt.get_unverified_header(ssd)
            jwt.decode(ssd, SFSsd.ret_ssd_pub_key(ssd_header['ssd_iss']),
                       algorithm='RS512')
        except Exception as ex:
            logger.debug("Error while validating SSD Token", ex)
            return False

        return True 
Example #22
Source File: jwt_token_extractor.py    From botbuilder-python with MIT License 5 votes vote down vote up
def _validate_token(
        self, jwt_token: str, channel_id: str, required_endorsements: List[str] = None
    ) -> ClaimsIdentity:
        required_endorsements = required_endorsements or []
        headers = jwt.get_unverified_header(jwt_token)

        # Update the signing tokens from the last refresh
        key_id = headers.get("kid", None)
        metadata = await self.open_id_metadata.get(key_id)

        if key_id and metadata.endorsements:
            # Verify that channelId is included in endorsements
            if not EndorsementsValidator.validate(channel_id, metadata.endorsements):
                raise Exception("Could not validate endorsement key")

            # Verify that additional endorsements are satisfied.
            # If no additional endorsements are expected, the requirement is satisfied as well
            for endorsement in required_endorsements:
                if not EndorsementsValidator.validate(
                    endorsement, metadata.endorsements
                ):
                    raise Exception("Could not validate endorsement key")

        if headers.get("alg", None) not in self.validation_parameters.algorithms:
            raise Exception("Token signing algorithm not in allowed list")

        options = {
            "verify_aud": False,
            "verify_exp": not self.validation_parameters.ignore_expiration,
        }

        decoded_payload = jwt.decode(
            jwt_token,
            metadata.public_key,
            leeway=self.validation_parameters.clock_tolerance,
            options=options,
        )

        claims = ClaimsIdentity(decoded_payload, True)

        return claims 
Example #23
Source File: registry_jwt.py    From quay with Apache License 2.0 4 votes vote down vote up
def decode_bearer_token(bearer_token, instance_keys, config):
    """
    decode_bearer_token decodes the given bearer token that contains both a Key ID as well as the
    encoded JWT and returns the decoded and validated JWT.

    On any error, raises an InvalidBearerTokenException with the reason for failure.
    """
    # Decode the key ID.
    try:
        headers = jwt.get_unverified_header(bearer_token)
    except jwtutil.InvalidTokenError as ite:
        logger.exception("Invalid token reason: %s", ite)
        raise InvalidBearerTokenException(ite)

    kid = headers.get("kid", None)
    if kid is None:
        logger.error("Missing kid header on encoded JWT: %s", bearer_token)
        raise InvalidBearerTokenException("Missing kid header")

    # Find the matching public key.
    public_key = instance_keys.get_service_key_public_key(kid)
    if public_key is None:
        logger.error(
            "Could not find requested service key %s with encoded JWT: %s", kid, bearer_token
        )
        raise InvalidBearerTokenException("Unknown service key")

    # Load the JWT returned.
    try:
        expected_issuer = instance_keys.service_name
        audience = config["SERVER_HOSTNAME"]
        max_signed_s = config.get("REGISTRY_JWT_AUTH_MAX_FRESH_S", 3660)
        max_exp = jwtutil.exp_max_s_option(max_signed_s)
        payload = jwtutil.decode(
            bearer_token,
            public_key,
            algorithms=[ALGORITHM],
            audience=audience,
            issuer=expected_issuer,
            options=max_exp,
            leeway=JWT_CLOCK_SKEW_SECONDS,
        )
    except jwtutil.InvalidTokenError as ite:
        logger.exception("Invalid token reason: %s", ite)
        raise InvalidBearerTokenException(ite)

    if not "sub" in payload:
        raise InvalidBearerTokenException("Missing sub field in JWT")

    return payload 
Example #24
Source File: client.py    From django_microsoft_auth with MIT License 4 votes vote down vote up
def get_claims(self, allow_refresh=True):
        if self.token is None:
            return None

        token = self.token["id_token"].encode("utf8")

        kid = jwt.get_unverified_header(token)["kid"]
        jwk = None
        public_key = None
        for key in self.jwks:
            if kid == key["kid"]:
                jwk = key
                break

        if jwk is None:
            if allow_refresh:
                logger.warn(
                    "could not find public key for id_token, "
                    "refreshing OIDC config"
                )
                cache.delete(CACHE_KEY_JWKS)
                cache.delete(CACHE_KEY_OPENID)

                return self.get_claims(allow_refresh=False)
            else:
                logger.warn("could not find public key for id_token")
                return None

        public_key = RSAAlgorithm.from_jwk(json.dumps(jwk))

        try:
            claims = jwt.decode(
                token,
                public_key,
                algoithm="RS256",
                audience=self.config.MICROSOFT_AUTH_CLIENT_ID,
            )
        except jwt.PyJWTError as e:
            logger.warn("could verify id_token sig: {}".format(e))
            return None

        return claims 
Example #25
Source File: utils.py    From flask-jwt-extended with MIT License 4 votes vote down vote up
def decode_token(encoded_token, csrf_value=None, allow_expired=False):
    """
    Returns the decoded token (python dict) from an encoded JWT. This does all
    the checks to insure that the decoded token is valid before returning it.

    :param encoded_token: The encoded JWT to decode into a python dict.
    :param csrf_value: Expected CSRF double submit value (optional)
    :param allow_expired: Options to ignore exp claim validation in token
    :return: Dictionary containing contents of the JWT
    """
    jwt_manager = _get_jwt_manager()
    unverified_claims = jwt.decode(
        encoded_token, verify=False, algorithms=config.decode_algorithms
    )
    unverified_headers = jwt.get_unverified_header(encoded_token)
    # Attempt to call callback with both claims and headers, but fallback to just claims
    # for backwards compatibility
    try:
        secret = jwt_manager._decode_key_callback(unverified_claims, unverified_headers)
    except TypeError:
        msg = (
            "The single-argument (unverified_claims) form of decode_key_callback ",
            "is deprecated. Update your code to use the two-argument form ",
            "(unverified_claims, unverified_headers)."
        )
        warn(msg, DeprecationWarning)
        secret = jwt_manager._decode_key_callback(unverified_claims)

    try:
        return decode_jwt(
            encoded_token=encoded_token,
            secret=secret,
            algorithms=config.decode_algorithms,
            identity_claim_key=config.identity_claim_key,
            user_claims_key=config.user_claims_key,
            csrf_value=csrf_value,
            audience=config.audience,
            issuer=config.decode_issuer,
            leeway=config.leeway,
            allow_expired=allow_expired
        )
    except ExpiredSignatureError:
        expired_token = decode_jwt(
            encoded_token=encoded_token,
            secret=secret,
            algorithms=config.decode_algorithms,
            identity_claim_key=config.identity_claim_key,
            user_claims_key=config.user_claims_key,
            csrf_value=csrf_value,
            audience=config.audience,
            issuer=config.decode_issuer,
            leeway=config.leeway,
            allow_expired=True
        )
        ctx_stack.top.expired_jwt = expired_token
        raise 
Example #26
Source File: utils.py    From django-rest-framework-sso with MIT License 4 votes vote down vote up
def decode_jwt_token(token):
    unverified_header = jwt.get_unverified_header(token)
    unverified_claims = jwt.decode(token, verify=False)

    if unverified_header.get(claims.KEY_ID):
        unverified_key_id = str(unverified_header.get(claims.KEY_ID))
    else:
        unverified_key_id = None

    if claims.ISSUER not in unverified_claims:
        raise MissingRequiredClaimError(claims.ISSUER)

    unverified_issuer = str(unverified_claims[claims.ISSUER])

    if api_settings.ACCEPTED_ISSUERS is not None and unverified_issuer not in api_settings.ACCEPTED_ISSUERS:
        raise InvalidIssuerError("Invalid issuer")

    public_key, key_id = get_public_key_and_key_id(issuer=unverified_issuer, key_id=unverified_key_id)

    options = {
        "verify_exp": api_settings.VERIFY_EXPIRATION,
        "verify_iss": api_settings.VERIFY_ISSUER,
        "verify_aud": api_settings.VERIFY_AUDIENCE,
    }

    payload = jwt.decode(
        jwt=token,
        key=public_key,
        verify=api_settings.VERIFY_SIGNATURE,
        algorithms=api_settings.DECODE_ALGORITHMS or [api_settings.ENCODE_ALGORITHM],
        options=options,
        leeway=api_settings.EXPIRATION_LEEWAY,
        audience=api_settings.IDENTITY,
        issuer=unverified_issuer,
    )

    if payload.get(claims.TOKEN) not in (claims.TOKEN_SESSION, claims.TOKEN_AUTHORIZATION):
        raise InvalidTokenError("Unknown token type")
    if not payload.get(claims.SESSION_ID):
        raise MissingRequiredClaimError("Session ID is missing.")
    if not payload.get(claims.USER_ID):
        raise MissingRequiredClaimError("User ID is missing.")

    return payload 
Example #27
Source File: msbot.py    From microsoftbotframework with MIT License 4 votes vote down vote up
def _verify_token(self, request, forced_refresh=False):
        authorization_header = request.headers['Authorization']
        token = authorization_header[7:]
        authorization_scheme = authorization_header[:6]
        token_headers = jwt.get_unverified_header(token)

        # Get valid signing keys
        if self.cache_certs:
            valid_certificates = self._get_stored_certificates(forced_refresh=forced_refresh)
        else:
            valid_certificates = self._get_remote_certificates()

        # 1. The token was sent in the HTTP Authorization header with 'Bearer' scheme
        if authorization_scheme != "Bearer":
            self.logger.warning('The token was not sent in the http authorisation header with the Bearer scheme.')
            return False

        # 2. The token is valid JSON that conforms to the JWT standard (see references)
        # 4. The token contains an audience claim with a value equivalent to your bot's Microsoft App ID.
        # 5. The token has not yet expired. Industry-standard clock-skew is 5 minutes.
        # 6. The token has a valid cryptographic signature with a key listed in the OpenId keys document retrieved in step 1, above.
        decoded_jwt = None
        for dict_key in valid_certificates['keys']:
            if dict_key['kid'] == token_headers['kid']:
                key = json.dumps(dict_key)

                algo = RSAAlgorithm('SHA256')
                public_key = algo.from_jwk(key)

                try:
                    decoded_jwt = jwt.decode(token, public_key, algorithms=['RS256'], audience=self.app_client_id)
                except jwt.exceptions.InvalidTokenError as e:
                    self.logger.warning('{}'.format(e))

        if decoded_jwt is None:
            if self.cache_certs and not forced_refresh:
                # Force cache refresh
                self.logger.warning('Forcing cache refresh as no valid certificate was found.')
                self._get_remote_certificates()
                return self._verify_token(request, forced_refresh=True)

            self.logger.warning('No valid certificate was found to verify JWT')
            return False

        if decoded_jwt is None:
            return False

        # 3. The token contains an issuer claim with value of https://api.botframework.com
        if decoded_jwt['iss'] != 'https://api.botframework.com':
            self.logger.warning('The token issuer claim had the incorrect value of {}'.format(decoded_jwt['iss']))
            return False

        self.logger.info('Token was validated - {}'.format(json.dumps(decoded_jwt)))
        return decoded_jwt