def test_rsa_should_accept_unicode_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path("testkey_rsa.priv"), "r") as rsa_key: algo.prepare_key(force_unicode(rsa_key.read()))
def test_rsa_should_parse_pem_public_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path("testkey2_rsa.pub.pem"), "r") as pem_key: algo.prepare_key(pem_key.read())
def test_rsa_should_accept_pem_private_key_bytes(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path("testkey_rsa.priv"), "rb") as pem_key: algo.prepare_key(pem_key.read())
def test_rsa_from_jwk_raises_exception_on_invalid_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path("jwk_hmac.json")) as keyfile: with pytest.raises(InvalidKeyError): algo.from_jwk(keyfile.read())
def test_rsa_to_jwk_raises_exception_on_invalid_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with pytest.raises(InvalidKeyError): algo.to_jwk({"not": "a valid key"})
def test_rsa_should_reject_non_string_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with pytest.raises(TypeError): algo.prepare_key(None)
def test_rsa_should_accept_unicode_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path('testkey_rsa'), 'r') as rsa_key: algo.prepare_key(ensure_unicode(rsa_key.read()))
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_redis_certificates() 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.app.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.app.logger.warning('{}'.format(e)) return False if decoded_jwt is None: if self.cache_certs and not forced_refresh: # Force cache refresh self.app.logger.warning( 'Forcing cache refresh as no valid certificate was found.') self._get_remote_certificates() return self._verify_token(request, forced_refresh=True) self.app.logger.warning( 'No valid certificate was found to verify JWT') 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.app.logger.warning( 'The token issuer claim had the incorrect value of {}'.format( decoded_jwt['iss'])) return False self.app.logger.info('Token was validated - {}'.format( json.dumps(decoded_jwt))) return decoded_jwt