def __init__(self, client_id, tenant_id, certificate_path, **kwargs): # pylint:disable=unused-argument # type: (str, str, str, Mapping[str, Any]) -> None if not certificate_path: # TODO: support PFX raise ValueError( "certificate_path must be the path to a PEM file containing an " "x509 certificate and its private key, not protected with a password" ) super(CertificateCredentialBase, self).__init__() with open(certificate_path, "rb") as f: pem_bytes = f.read() # TODO: support pem password private_key = serialization.load_pem_private_key( pem_bytes, password=None, backend=default_backend()) cert = x509.load_pem_x509_certificate(pem_bytes, default_backend()) fingerprint = cert.fingerprint(hashes.SHA1()) self._auth_url = Endpoints.AAD_OAUTH2_V2_FORMAT.format(tenant_id) self._client_id = client_id self._signer = JwtSigner(private_key, "RS256", sha1_thumbprint=binascii.hexlify(fingerprint))
def __init__(self, tenant_id, client_id, certificate_path, **kwargs): # pylint:disable=unused-argument # type: (str, str, str, **Any) -> None if not certificate_path: raise ValueError( "'certificate_path' must be the path to a PEM file containing an x509 certificate and its private key" ) super(CertificateCredentialBase, self).__init__() password = kwargs.pop("password", None) if isinstance(password, six.text_type): password = password.encode(encoding="utf-8") with open(certificate_path, "rb") as f: pem_bytes = f.read() private_key = serialization.load_pem_private_key( pem_bytes, password=password, backend=default_backend()) cert = x509.load_pem_x509_certificate(pem_bytes, default_backend()) fingerprint = cert.fingerprint(hashes.SHA1()) #nosec self._client = self._get_auth_client(tenant_id, **kwargs) self._client_id = client_id self._signer = JwtSigner(private_key, "RS256", sha1_thumbprint=binascii.hexlify(fingerprint))
def setUpClass(cls): http_client = MinimalHttpClient() if "client_certificate" in CONFIG: private_key_path = CONFIG["client_certificate"]["private_key_path"] with open(os.path.join(THIS_FOLDER, private_key_path)) as f: private_key = f.read() # Expecting PEM format cls.client = Client( CONFIG["openid_configuration"], CONFIG['client_id'], http_client=http_client, client_assertion=JwtSigner( private_key, algorithm="RS256", sha1_thumbprint=CONFIG["client_certificate"]["thumbprint"] ).sign_assertion( audience=CONFIG["openid_configuration"]["token_endpoint"], issuer=CONFIG["client_id"], ), client_assertion_type=Client.CLIENT_ASSERTION_TYPE_JWT, ) else: cls.client = Client(CONFIG["openid_configuration"], CONFIG['client_id'], http_client=http_client, client_secret=CONFIG.get('client_secret'))
def __init__(self, client_id, tenant_id, certificate_path, **kwargs): # type: (str, str, str, Mapping[str, Any]) -> None if not certificate_path: # TODO: support PFX raise ValueError( "certificate_path must be the path to a PEM-encoded private key file" ) super(CertificateCredentialBase, self).__init__() auth_url = Endpoints.AAD_OAUTH2_V2_FORMAT.format(tenant_id) with open(certificate_path) as pem: private_key = pem.read() signer = JwtSigner(private_key, "RS256") client_assertion = signer.sign_assertion(audience=auth_url, issuer=client_id) self._form_data = { "client_assertion": client_assertion, "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", "client_id": client_id, "grant_type": "client_credentials", }
class CertificateCredentialBase(ABC): """Sans I/O base for certificate credentials""" def __init__(self, tenant_id, client_id, certificate_path, **kwargs): # pylint:disable=unused-argument # type: (str, str, str, **Any) -> None if not certificate_path: raise ValueError( "'certificate_path' must be the path to a PEM file containing an x509 certificate and its private key" ) super(CertificateCredentialBase, self).__init__() password = kwargs.pop("password", None) if isinstance(password, six.text_type): password = password.encode(encoding="utf-8") with open(certificate_path, "rb") as f: pem_bytes = f.read() private_key = serialization.load_pem_private_key( pem_bytes, password=password, backend=default_backend()) cert = x509.load_pem_x509_certificate(pem_bytes, default_backend()) fingerprint = cert.fingerprint(hashes.SHA1()) #nosec self._client = self._get_auth_client(tenant_id, **kwargs) self._client_id = client_id self._signer = JwtSigner(private_key, "RS256", sha1_thumbprint=binascii.hexlify(fingerprint)) def _get_request_data(self, *scopes): assertion = self._signer.sign_assertion(audience=self._client.auth_url, issuer=self._client_id) if isinstance(assertion, six.binary_type): assertion = assertion.decode("utf-8") return { "client_assertion": assertion, "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", "client_id": self._client_id, "grant_type": "client_credentials", "scope": " ".join(scopes), } @abc.abstractmethod def _get_auth_client(self, tenant_id, **kwargs): pass
class CertificateCredentialBase(object): """Sans I/O base for certificate credentials""" def __init__(self, client_id, tenant_id, certificate_path, **kwargs): # pylint:disable=unused-argument # type: (str, str, str, Mapping[str, Any]) -> None if not certificate_path: # TODO: support PFX raise ValueError( "certificate_path must be the path to a PEM file containing an " "x509 certificate and its private key, not protected with a password" ) super(CertificateCredentialBase, self).__init__() with open(certificate_path, "rb") as f: pem_bytes = f.read() # TODO: support pem password private_key = serialization.load_pem_private_key( pem_bytes, password=None, backend=default_backend()) cert = x509.load_pem_x509_certificate(pem_bytes, default_backend()) fingerprint = cert.fingerprint(hashes.SHA1()) self._auth_url = Endpoints.AAD_OAUTH2_V2_FORMAT.format(tenant_id) self._client_id = client_id self._signer = JwtSigner(private_key, "RS256", sha1_thumbprint=binascii.hexlify(fingerprint)) def _get_request_data(self, *scopes): assertion = self._signer.sign_assertion(audience=self._auth_url, issuer=self._client_id) return { "client_assertion": assertion, "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", "client_id": self._client_id, "grant_type": "client_credentials", "scope": " ".join(scopes) }
def test_extra_claims(self): assertion = JwtSigner(key=None, algorithm="none").sign_assertion( "audience", "issuer", additional_claims={"client_ip": "1.2.3.4"}) payload = json.loads( base64decode(assertion.split(b'.')[1].decode('utf-8'))) self.assertEqual("1.2.3.4", payload.get("client_ip"))