-
Notifications
You must be signed in to change notification settings - Fork 3.3k
address review feedback #21109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
address review feedback #21109
Changes from 9 commits
ad57965
7afd716
b7de7bc
067adc1
0f8a317
dea2f29
e670b39
34cd5d9
da98070
c712de7
ca86cf4
4388cf6
1f50449
8806099
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,7 +3,7 @@ | |
| # Licensed under the MIT License. | ||
| # ------------------------------------ | ||
| import time | ||
| from typing import cast, TYPE_CHECKING | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| import six | ||
|
|
||
|
|
@@ -33,42 +33,51 @@ class OnBehalfOfCredential(MsalCredential, GetTokenMixin): | |
|
|
||
| :param str tenant_id: ID of the service principal's tenant. Also called its "directory" ID. | ||
| :param str client_id: the service principal's client ID | ||
| :param client_credential: a credential to authenticate the service principal, either one of its client secrets (a | ||
| string) or the bytes of a certificate in PEM or PKCS12 format including the private key | ||
| :type client_credential: str or bytes | ||
| :param str user_assertion: the access token the credential will use as the user assertion when requesting | ||
| on-behalf-of tokens | ||
| :keyword str client_secret: Optional. client secrets to authenticate the service principal. | ||
| Either client_secret or client_certificate must be provided. | ||
| :keyword bytes client_certificate: Optional. the bytes of a certificate in PEM or PKCS12 format including | ||
| the private key to authenticate the service principal. Either client_secret or client_certificate must | ||
| be provided. | ||
| :keyword str user_assertion: Required. the access token the credential will use as the user assertion when | ||
|
xiangyan99 marked this conversation as resolved.
Outdated
|
||
| requesting on-behalf-of tokens | ||
|
|
||
| :keyword str authority: Authority of an Azure Active Directory endpoint, for example "login.microsoftonline.com", | ||
| the authority for Azure Public Cloud (which is the default). :class:`~azure.identity.AzureAuthorityHosts` | ||
| defines authorities for other clouds. | ||
| :keyword password: a certificate password. Used only when **client_credential** is certificate bytes. If this value | ||
| :keyword password: a certificate password. Used only when **client_certificate** is provided. If this value | ||
| is a unicode string, it will be encoded as UTF-8. If the certificate requires a different encoding, pass | ||
| appropriately encoded bytes instead. | ||
| :paramtype password: str or bytes | ||
| """ | ||
|
|
||
| def __init__(self, tenant_id, client_id, client_credential, user_assertion, **kwargs): | ||
| # type: (str, str, Union[bytes, str], str, **Any) -> None | ||
| credential = cast("Union[Dict, str]", client_credential) | ||
| if isinstance(client_credential, six.binary_type): | ||
| def __init__(self, tenant_id, client_id, **kwargs): | ||
| # type: (str, str, **Any) -> None | ||
| self._assertion = kwargs.pop("user_assertion", None) | ||
| if not self._assertion: | ||
| raise ValueError('"user_assertion" is required.') | ||
| client_certificate = kwargs.pop("client_certificate", None) | ||
| client_secret = kwargs.pop("client_secret", None) | ||
|
|
||
| if client_certificate: | ||
| try: | ||
| credential = get_client_credential( | ||
| certificate_path=None, password=kwargs.pop("password", None), certificate_data=client_credential | ||
| certificate_path=None, password=kwargs.pop("password", None), certificate_data=client_certificate | ||
| ) | ||
| except ValueError as ex: | ||
| # client_credential isn't a valid cert. On 2.7 str == bytes and we ignore this exception because we | ||
| # can't tell whether the caller intended to provide a cert. On Python 3 we can say the caller provided | ||
| # either an invalid cert, or a client secret as bytes; both are errors. | ||
| if six.PY3: | ||
| message = ( | ||
| '"client_credential" should be either a client secret (a string)' | ||
| + " or the bytes of a certificate in PEM or PKCS12 format" | ||
| '"client_certificate" should be the bytes of a certificate in PEM or PKCS12 format' | ||
|
xiangyan99 marked this conversation as resolved.
Outdated
|
||
| ) | ||
| six.raise_from(ValueError(message), ex) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove the |
||
| elif client_secret: | ||
| credential = client_secret | ||
| else: | ||
| raise ValueError("Either `client_certificate` or `client_secret` must be provided") | ||
|
|
||
| super(OnBehalfOfCredential, self).__init__(client_id, credential, tenant_id=tenant_id, **kwargs) | ||
| self._assertion = user_assertion | ||
| self._auth_record = None # type: Optional[AuthenticationRecord] | ||
|
|
||
| @wrap_exceptions | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,16 +30,18 @@ class OnBehalfOfCredential(AsyncContextManager, GetTokenMixin): | |
|
|
||
| :param str tenant_id: ID of the service principal's tenant. Also called its "directory" ID. | ||
| :param str client_id: the service principal's client ID | ||
| :param client_credential: a credential to authenticate the service principal, either one of its client secrets (a | ||
| string) or the bytes of a certificate in PEM or PKCS12 format including the private key | ||
| :paramtype client_credential: str or bytes | ||
| :param str user_assertion: the access token the credential will use as the user assertion when requesting | ||
| on-behalf-of tokens | ||
| :keyword str client_secret: Optional. client secrets to authenticate the service principal. | ||
| Either client_secret or client_certificate must be provided. | ||
| :keyword bytes client_certificate: Optional. the bytes of a certificate in PEM or PKCS12 format including | ||
| the private key to authenticate the service principal. Either client_secret or client_certificate must | ||
| be provided. | ||
| :keyword str user_assertion: Required. the access token the credential will use as the user assertion when | ||
| requesting on-behalf-of tokens | ||
|
|
||
| :keyword str authority: Authority of an Azure Active Directory endpoint, for example "login.microsoftonline.com", | ||
| the authority for Azure Public Cloud (which is the default). :class:`~azure.identity.AzureAuthorityHosts` | ||
| defines authorities for other clouds. | ||
| :keyword password: a certificate password. Used only when **client_credential** is certificate bytes. If this value | ||
| :keyword password: a certificate password. Used only when **client_certificate** is provided. If this value | ||
| is a unicode string, it will be encoded as UTF-8. If the certificate requires a different encoding, pass | ||
| appropriately encoded bytes instead. | ||
| :paramtype password: str or bytes | ||
|
|
@@ -49,31 +51,37 @@ def __init__( | |
| self, | ||
| tenant_id: str, | ||
| client_id: str, | ||
| client_credential: "Union[bytes, str]", | ||
| *, | ||
| client_certificate: bytes = None, | ||
| client_secret: str = None, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wish we had already dropped 2.7 support so we could do this for the sync credential 🥲 |
||
| user_assertion: str, | ||
| **kwargs: "Any" | ||
| ) -> None: | ||
| super().__init__() | ||
| validate_tenant_id(tenant_id) | ||
|
|
||
| if isinstance(client_credential, bytes): | ||
| self._assertion = user_assertion | ||
| if not self._assertion: | ||
| raise ValueError('"user_assertion" is required.') | ||
|
|
||
| if client_certificate: | ||
| try: | ||
| cert = get_client_credential(None, kwargs.pop("password", None), client_credential) | ||
| cert = get_client_credential(None, kwargs.pop("password", None), client_certificate) | ||
| except ValueError as ex: | ||
| message = ( | ||
| '"client_credential" should be either a client secret (a string)' | ||
| + " or the bytes of a certificate in PEM or PKCS12 format" | ||
| '"client_certificate" should be the bytes of a certificate in PEM or PKCS12 format' | ||
| ) | ||
| raise ValueError(message) from ex | ||
| self._client_credential = AadClientCertificate( | ||
| cert["private_key"], password=cert.get("passphrase") | ||
| ) # type: Union[str, AadClientCertificate] | ||
| elif client_secret: | ||
| self._client_credential = client_secret | ||
| else: | ||
| self._client_credential = client_credential | ||
| raise ValueError("Either `client_certificate` or `client_secret` must be provided") | ||
|
xiangyan99 marked this conversation as resolved.
Outdated
|
||
|
|
||
| # note AadClient handles "authority" and any pipeline kwargs | ||
| self._client = AadClient(tenant_id, client_id, **kwargs) | ||
| self._assertion = user_assertion | ||
|
|
||
| async def __aenter__(self): | ||
| await self._client.__aenter__() | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.