Skip to content

Commit fe68412

Browse files
authored
[Key Vault] Merge hotfix/keyvault-verify with main (Azure#26384)
1 parent 0e883ff commit fe68412

File tree

208 files changed

+4516
-4091
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

208 files changed

+4516
-4091
lines changed

.vscode/cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@
231231
"myacr",
232232
"mydirectory",
233233
"myfile",
234+
"myvault",
234235
"nazsdk",
235236
"nbytes",
236237
"noarch",

sdk/keyvault/azure-keyvault-administration/CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Release History
22

3-
## 4.2.0b1 (Unreleased)
3+
## 4.3.0b1 (Unreleased)
44

55
### Features Added
66

@@ -12,6 +12,13 @@
1212
- Updated minimum `azure-core` version to 1.24.0
1313
- Updated minimum `msrest` version to 0.7.1
1414

15+
## 4.2.0 (2022-09-19)
16+
17+
### Breaking Changes
18+
- Clients verify the challenge resource matches the vault domain. This should affect few customers,
19+
who can provide `verify_challenge_resource=False` to client constructors to disable.
20+
See https://aka.ms/azsdk/blog/vault-uri for more information.
21+
1522
## 4.1.1 (2022-08-11)
1623

1724
### Other Changes

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_access_control_client.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,16 @@ class KeyVaultAccessControlClient(KeyVaultClientBase):
2323
"""Manages role-based access to Azure Key Vault.
2424
2525
:param str vault_url: URL of the vault the client will manage. This is also called the vault's "DNS Name".
26-
:param credential: an object which can provide an access token for the vault, such as a credential from
26+
You should validate that this URL references a valid Key Vault or Managed HSM resource.
27+
See https://aka.ms/azsdk/blog/vault-uri for details.
28+
:param credential: An object which can provide an access token for the vault, such as a credential from
2729
:mod:`azure.identity`
30+
:type credential: :class:`~azure.core.credentials.TokenCredential`
31+
32+
:keyword api_version: Version of the service API to use. Defaults to the most recent.
33+
:paramtype api_version: ~azure.keyvault.administration.ApiVersion
34+
:keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key
35+
Vault or Managed HSM domain. Defaults to True.
2836
"""
2937

3038
# pylint:disable=protected-access

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_backup_client.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,16 @@ class KeyVaultBackupClient(KeyVaultClientBase):
3030
"""Performs Key Vault backup and restore operations.
3131
3232
:param str vault_url: URL of the vault on which the client will operate. This is also called the vault's "DNS Name".
33-
:param credential: an object which can provide an access token for the vault, such as a credential from
33+
You should validate that this URL references a valid Key Vault or Managed HSM resource.
34+
See https://aka.ms/azsdk/blog/vault-uri for details.
35+
:param credential: An object which can provide an access token for the vault, such as a credential from
3436
:mod:`azure.identity`
37+
:type credential: :class:`~azure.core.credentials.TokenCredential`
38+
39+
:keyword api_version: Version of the service API to use. Defaults to the most recent.
40+
:paramtype api_version: ~azure.keyvault.administration.ApiVersion
41+
:keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key
42+
Vault or Managed HSM domain. Defaults to True.
3543
"""
3644

3745
# pylint:disable=protected-access

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_challenge_auth_policy.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import time
1818
from typing import TYPE_CHECKING
19+
from urllib.parse import urlparse
1920

2021
from azure.core.pipeline.policies import AsyncBearerTokenCredentialPolicy
2122

@@ -36,6 +37,7 @@ def __init__(self, credential: "AsyncTokenCredential", *scopes: str, **kwargs: "
3637
super().__init__(credential, *scopes, **kwargs)
3738
self._credential = credential
3839
self._token = None # type: Optional[AccessToken]
40+
self._verify_challenge_resource = kwargs.pop("verify_challenge_resource", True)
3941

4042
async def on_request(self, request: "PipelineRequest") -> None:
4143
_enforce_tls(request)
@@ -69,6 +71,19 @@ async def on_challenge(self, request: "PipelineRequest", response: "PipelineResp
6971
except ValueError:
7072
return False
7173

74+
if self._verify_challenge_resource:
75+
resource_domain = urlparse(scope).netloc
76+
if not resource_domain:
77+
raise ValueError(f"The challenge contains invalid scope '{scope}'.")
78+
79+
request_domain = urlparse(request.http_request.url).netloc
80+
if not request_domain.lower().endswith(f".{resource_domain.lower()}"):
81+
raise ValueError(
82+
f"The challenge resource '{resource_domain}' does not match the requested domain. Pass "
83+
"`verify_challenge_resource=False` to your client's constructor to disable this verification. "
84+
"See https://aka.ms/azsdk/blog/vault-uri for more information."
85+
)
86+
7287
body = request.context.pop("key_vault_request_data", None)
7388
request.http_request.set_text_body(body) # no-op when text is None
7489
await self.authorize_request(request, scope, tenant_id=challenge.tenant_id)

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_client_base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ def __init__(self, vault_url: str, credential: "AsyncTokenCredential", **kwargs:
4949
}
5050
)
5151

52+
verify_challenge = kwargs.pop("verify_challenge_resource", True)
5253
self._client = _KeyVaultClient(
5354
api_version=api_version,
54-
authentication_policy=AsyncChallengeAuthPolicy(credential),
55+
authentication_policy=AsyncChallengeAuthPolicy(credential, verify_challenge_resource=verify_challenge),
5556
sdk_moniker=SDK_MONIKER,
5657
http_logging_policy=http_logging_policy,
5758
**kwargs

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/challenge_auth_policy.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""
1616

1717
import time
18+
from urllib.parse import urlparse
1819

1920
from azure.core.exceptions import ServiceRequestError
2021
from azure.core.pipeline import PipelineRequest
@@ -63,6 +64,7 @@ def __init__(self, credential, *scopes, **kwargs):
6364
super(ChallengeAuthPolicy, self).__init__(credential, *scopes, **kwargs)
6465
self._credential = credential
6566
self._token = None # type: Optional[AccessToken]
67+
self._verify_challenge_resource = kwargs.pop("verify_challenge_resource", True)
6668

6769
def on_request(self, request):
6870
# type: (PipelineRequest) -> None
@@ -97,6 +99,19 @@ def on_challenge(self, request, response):
9799
except ValueError:
98100
return False
99101

102+
if self._verify_challenge_resource:
103+
resource_domain = urlparse(scope).netloc
104+
if not resource_domain:
105+
raise ValueError(f"The challenge contains invalid scope '{scope}'.")
106+
107+
request_domain = urlparse(request.http_request.url).netloc
108+
if not request_domain.lower().endswith(f".{resource_domain.lower()}"):
109+
raise ValueError(
110+
f"The challenge resource '{resource_domain}' does not match the requested domain. Pass "
111+
"`verify_challenge_resource=False` to your client's constructor to disable this verification. "
112+
"See https://aka.ms/azsdk/blog/vault-uri for more information."
113+
)
114+
100115
body = request.context.pop("key_vault_request_data", None)
101116
request.http_request.set_text_body(body) # no-op when text is None
102117
self.authorize_request(request, scope, tenant_id=challenge.tenant_id)

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/client_base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,10 @@ def __init__(self, vault_url, credential, **kwargs):
5858
{"x-ms-keyvault-network-info", "x-ms-keyvault-region", "x-ms-keyvault-service-version"}
5959
)
6060

61+
verify_challenge = kwargs.pop("verify_challenge_resource", True)
6162
self._client = _KeyVaultClient(
6263
api_version=api_version,
63-
authentication_policy=ChallengeAuthPolicy(credential),
64+
authentication_policy=ChallengeAuthPolicy(credential, verify_challenge_resource=verify_challenge),
6465
sdk_moniker=SDK_MONIKER,
6566
http_logging_policy=http_logging_policy,
6667
**kwargs

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
# Licensed under the MIT License.
44
# ------------------------------------
55

6-
VERSION = "4.2.0b1"
6+
VERSION = "4.3.0b1"

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_access_control_client.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,16 @@ class KeyVaultAccessControlClient(AsyncKeyVaultClientBase):
2424
"""Manages role-based access to Azure Key Vault.
2525
2626
:param str vault_url: URL of the vault the client will manage. This is also called the vault's "DNS Name".
27-
:param credential: an object which can provide an access token for the vault, such as a credential from
28-
:mod:`azure.identity`
27+
You should validate that this URL references a valid Key Vault or Managed HSM resource.
28+
See https://aka.ms/azsdk/blog/vault-uri for details.
29+
:param credential: An object which can provide an access token for the vault, such as a credential from
30+
:mod:`azure.identity.aio`
31+
:type credential: :class:`~azure.core.credentials_async.AsyncTokenCredential`
32+
33+
:keyword api_version: Version of the service API to use. Defaults to the most recent.
34+
:paramtype api_version: ~azure.keyvault.administration.ApiVersion
35+
:keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key
36+
Vault or Managed HSM domain. Defaults to True.
2937
"""
3038

3139
# pylint:disable=protected-access

0 commit comments

Comments
 (0)