Skip to content

Commit fc95f8d

Browse files
authored
[Identity] Align samples with other languages (#20966)
1 parent 5ed3bcc commit fc95f8d

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

sdk/identity/azure-identity/samples/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ pip install azure-identity azure-keyvault-certificates azure-keyvault-secrets
3434
| File | Description |
3535
|-------------|-------------|
3636
| control_interactive_prompts.py | demonstrates controlling when interactive credentials prompt for user interaction |
37-
| custom_credentials.py | demonstrates custom credential implementation |
37+
| custom_credentials.py | demonstrates custom credential implementations using existing access tokens and an MSAL client |
3838
| key_vault_cert.py | demonstrates authenticating with a Key Vault certificate |
39-
| user_authentication.py | demonstrates user authentication API for applications |
39+
| user_authentication.py | demonstrates user authentication and token cache persistence API for applications |

sdk/identity/azure-identity/samples/custom_credentials.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
# Copyright (c) Microsoft Corporation.
33
# Licensed under the MIT License.
44
# ------------------------------------
5-
"""Demonstrates custom credential implementation"""
5+
"""Demonstrates custom credential implementations using existing access tokens and an MSAL client"""
66

7+
import time
78
from typing import TYPE_CHECKING
89

910
from azure.core.credentials import AccessToken
11+
from azure.identity import AuthenticationRequiredError, AzureAuthorityHosts
12+
import msal
1013

1114
if TYPE_CHECKING:
1215
from typing import Any, Union
@@ -32,3 +35,25 @@ def get_token(self, *scopes, **kwargs):
3235
"""get_token is the only method a credential must implement"""
3336

3437
return self._token
38+
39+
40+
class MsalTokenCredential(object):
41+
"""Uses an MSAL client directly to obtain access tokens with an interactive flow."""
42+
def __init__(self, tenant_id, client_id):
43+
# type: (str, str) -> None
44+
self._app = msal.PublicClientApplication(
45+
client_id=client_id, authority="https://{}/{}".format(AzureAuthorityHosts.AZURE_PUBLIC_CLOUD, tenant_id)
46+
)
47+
48+
def get_token(self, *scopes, **kwargs):
49+
# type: (*str, **Any) -> AccessToken
50+
"""get_token is the only method a credential must implement"""
51+
52+
now = int(time.time())
53+
result = self._app.acquire_token_interactive(list(scopes), **kwargs)
54+
55+
try:
56+
return AccessToken(result["access_token"], now + int(result["expires_in"]))
57+
except:
58+
print("\nFailed to get a valid access token")
59+
raise AuthenticationRequiredError(scopes)

sdk/identity/azure-identity/samples/user_authentication.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
# The 'authenticate' method begins interactive authentication. Call it whenever it's convenient
2626
# for your application to authenticate a user. It returns a record of the authentication.
2727
record = credential.authenticate()
28+
print("\nAuthenticated first credential")
2829

2930
# The record contains no authentication secrets. You can serialize it to JSON for storage.
3031
record_json = record.serialize()
@@ -33,6 +34,7 @@
3334
# without prompting for authentication again.
3435
client = SecretClient(VAULT_URL, credential)
3536
secret_names = [s.name for s in client.list_properties_of_secrets()]
37+
print("\nCompleted request with first credential")
3638

3739
# An authentication record stored by your application enables other credentials to access data from
3840
# past authentications. If the cache contains sufficient data, this eliminates the need for your
@@ -45,3 +47,14 @@
4547
# This request should also succeed without prompting for authentication.
4648
client = SecretClient(VAULT_URL, new_credential)
4749
secret_names = [s.name for s in client.list_properties_of_secrets()]
50+
print("\nCompleted request with credential using shared cache")
51+
52+
# To isolate the token cache from other applications, you can provide a cache name to TokenCachePersistenceOptions.
53+
separate_cache_credential = InteractiveBrowserCredential(
54+
cache_persistence_options=TokenCachePersistenceOptions(name="my_app"), authentication_record=deserialized_record
55+
)
56+
57+
# This request should prompt for authentication since the credential is using a separate cache.
58+
client = SecretClient(VAULT_URL, separate_cache_credential)
59+
secret_names = [s.name for s in client.list_properties_of_secrets()]
60+
print("\nCompleted request with credential using separate cache")

0 commit comments

Comments
 (0)