Skip to content

Commit 374120b

Browse files
authored
Chriss/token cache peristence options doc improvements (Azure#23908)
* Add example to TokenCachePersistenceOptions
1 parent 33cfc7e commit 374120b

10 files changed

+103
-44
lines changed

sdk/identity/Azure.Identity/samples/ClientSideUserAuthentication.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ In many cases applications require tight control over user interaction. In these
4040

4141
```C# Snippet:Identity_ClientSideUserAuthentication_DisableAutomaticAuthentication
4242
var credential = new InteractiveBrowserCredential(
43-
new InteractiveBrowserCredentialOptions
44-
{
45-
DisableAutomaticAuthentication = true
46-
});
43+
new InteractiveBrowserCredentialOptions { DisableAutomaticAuthentication = true });
4744

4845
await credential.AuthenticateAsync();
4946

@@ -87,10 +84,7 @@ To configure a credential, such as the `InteractiveBrowserCredential`, to persis
8784

8885
```C# Snippet:Identity_ClientSideUserAuthentication_Persist_TokenCache
8986
var credential = new InteractiveBrowserCredential(
90-
new InteractiveBrowserCredentialOptions
91-
{
92-
TokenCachePersistenceOptions = new TokenCachePersistenceOptions()
93-
});
87+
new InteractiveBrowserCredentialOptions { TokenCachePersistenceOptions = new TokenCachePersistenceOptions() });
9488
```
9589

9690
### Persisting the AuthenticationRecord
@@ -130,8 +124,7 @@ using (var authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Open, Fi
130124
var credential = new InteractiveBrowserCredential(
131125
new InteractiveBrowserCredentialOptions
132126
{
133-
TokenCachePersistenceOptions = new TokenCachePersistenceOptions(),
134-
AuthenticationRecord = authRecord
127+
TokenCachePersistenceOptions = new TokenCachePersistenceOptions(), AuthenticationRecord = authRecord
135128
});
136129
```
137130

sdk/identity/Azure.Identity/src/AuthenticationRecord.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace Azure.Identity
1414
/// <summary>
1515
/// Account information relating to an authentication request.
1616
/// </summary>
17+
/// <seealso cref="TokenCachePersistenceOptions"/>.
1718
public class AuthenticationRecord
1819
{
1920
internal const string CurrentVersion = "1.0";

sdk/identity/Azure.Identity/src/ClientCertificateCredentialOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Azure.Identity
99
public class ClientCertificateCredentialOptions : TokenCredentialOptions, ITokenCacheOptions
1010
{
1111
/// <summary>
12-
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted.
12+
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted to disk.
1313
/// </summary>
1414
public TokenCachePersistenceOptions TokenCachePersistenceOptions { get; set; }
1515

sdk/identity/Azure.Identity/src/ClientSecretCredentialOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Azure.Identity
99
public class ClientSecretCredentialOptions : TokenCredentialOptions, ITokenCacheOptions
1010
{
1111
/// <summary>
12-
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted.
12+
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted to disk.
1313
/// </summary>
1414
public TokenCachePersistenceOptions TokenCachePersistenceOptions { get; set; }
1515

sdk/identity/Azure.Identity/src/DeviceCodeCredentialOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public string TenantId
3535
public string ClientId { get; set; } = Constants.DeveloperSignOnClientId;
3636

3737
/// <summary>
38-
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted.
38+
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted to disk.
3939
/// </summary>
4040
public TokenCachePersistenceOptions TokenCachePersistenceOptions { get; set; }
4141

sdk/identity/Azure.Identity/src/InteractiveBrowserCredential.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public virtual AuthenticationRecord Authenticate(CancellationToken cancellationT
9797
}
9898

9999
/// <summary>
100-
/// Interactively authenticates a user via the default browser.
100+
/// Interactively authenticates a user via the default browser. The resulting <see cref="AuthenticationRecord"/> will automatically be used in subsequent calls to <see cref="GetTokenAsync"/>.
101101
/// </summary>
102102
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
103103
/// <returns>The result of the authentication request, containing the acquired <see cref="AccessToken"/>, and the <see cref="AuthenticationRecord"/> which can be used to silently authenticate the account.</returns>
@@ -110,7 +110,7 @@ public virtual async Task<AuthenticationRecord> AuthenticateAsync(CancellationTo
110110
}
111111

112112
/// <summary>
113-
/// Interactively authenticates a user via the default browser.
113+
/// Interactively authenticates a user via the default browser. The resulting <see cref="AuthenticationRecord"/> will automatically be used in subsequent calls to <see cref="GetToken"/>.
114114
/// </summary>
115115
/// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
116116
/// <param name="requestContext">The details of the authentication request.</param>

sdk/identity/Azure.Identity/src/InteractiveBrowserCredentialOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public string TenantId
3434
public string ClientId { get; set; } = Constants.DeveloperSignOnClientId;
3535

3636
/// <summary>
37-
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted.
37+
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted to disk.
3838
/// </summary>
3939
public TokenCachePersistenceOptions TokenCachePersistenceOptions { get; set; }
4040

sdk/identity/Azure.Identity/src/TokenCachePersistenceOptions.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,59 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

44
namespace Azure.Identity
55
{
66
/// <summary>
77
/// Options controlling the storage of the token cache.
88
/// </summary>
9+
/// <example>
10+
/// <para>
11+
/// This is an example showing how TokenCachePersistenceOptions and an AuthenticationRecord can be used together to enable silent authentication
12+
/// across executions of a client application.
13+
/// </para>
14+
/// <code snippet="Snippet:AuthenticationRecord_TokenCachePersistenceOptions" language="csharp">
15+
/// const string TOKEN_CACHE_NAME = &quot;MyTokenCache&quot;;
16+
/// InteractiveBrowserCredential credential;
17+
/// AuthenticationRecord authRecord;
18+
///
19+
/// // Check if an AuthenticationRecord exists on disk.
20+
/// // If it does not exist, get one and serialize it to disk.
21+
/// // If it does exist, load it from disk and deserialize it.
22+
/// if (!File.Exists(AUTH_RECORD_PATH))
23+
/// {
24+
/// // Construct a credential with TokenCachePersistenceOptions specified to ensure that the token cache is persisted to disk.
25+
/// // We can also optionally specify a name for the cache to avoid having it cleared by other applications.
26+
/// credential = new InteractiveBrowserCredential(
27+
/// new InteractiveBrowserCredentialOptions { TokenCachePersistenceOptions = new TokenCachePersistenceOptions { Name = TOKEN_CACHE_NAME } });
28+
///
29+
/// // Call AuthenticateAsync to fetch a new AuthenticationRecord.
30+
/// authRecord = await credential.AuthenticateAsync();
31+
///
32+
/// // Serialize the AuthenticationRecord to disk so that it can be re-used across executions of this initialization code.
33+
/// using var authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Create, FileAccess.Write);
34+
/// await authRecord.SerializeAsync(authRecordStream);
35+
/// }
36+
/// else
37+
/// {
38+
/// // Load the previously serialized AuthenticationRecord from disk and deserialize it.
39+
/// using var authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Open, FileAccess.Read);
40+
/// authRecord = await AuthenticationRecord.DeserializeAsync(authRecordStream);
41+
///
42+
/// // Construct a new client with our TokenCachePersistenceOptions with the addition of the AuthenticationRecord property.
43+
/// // This tells the credential to use the same token cache in addition to which account to try and fetch from cache when GetToken is called.
44+
/// credential = new InteractiveBrowserCredential(
45+
/// new InteractiveBrowserCredentialOptions
46+
/// {
47+
/// TokenCachePersistenceOptions = new TokenCachePersistenceOptions { Name = TOKEN_CACHE_NAME },
48+
/// AuthenticationRecord = authRecord
49+
/// });
50+
/// }
51+
///
52+
/// // Construct our client with the credential which is connected to the token cache
53+
/// // with the capability of silent authentication for the account specified in the AuthenticationRecord.
54+
/// var client = new SecretClient(new Uri(&quot;https://myvault.vault.azure.net/&quot;), credential);
55+
/// </code>
56+
/// </example>
957
public class TokenCachePersistenceOptions
1058
{
1159
/// <summary>

sdk/identity/Azure.Identity/src/UsernamePasswordCredentialOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Azure.Identity
99
public class UsernamePasswordCredentialOptions : TokenCredentialOptions, ITokenCacheOptions
1010
{
1111
/// <summary>
12-
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted.
12+
/// Specifies the <see cref="TokenCachePersistenceOptions"/> to be used by the credential. If not options are specified, the token cache will not be persisted to disk.
1313
/// </summary>
1414
public TokenCachePersistenceOptions TokenCachePersistenceOptions { get; set; }
1515
}

sdk/identity/Azure.Identity/tests/samples/UserAuthenticationSnippets.cs

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,52 @@ namespace Azure.Identity.Samples
1515
public class UserAuthenticationSnippets
1616
{
1717
#region Snippet:Identity_ClientSideUserAuthentication_Persist_TokenCache_AuthRecordPath
18+
1819
private const string AUTH_RECORD_PATH = "./tokencache.bin";
20+
1921
#endregion
2022

2123
public void Identity_ClientSideUserAuthentication_SimpleInteractiveBrowser()
2224
{
2325
#region Snippet:Identity_ClientSideUserAuthentication_SimpleInteractiveBrowser
26+
2427
var client = new SecretClient(
2528
new Uri("https://myvault.vault.azure.net/"),
2629
new InteractiveBrowserCredential()
2730
);
31+
2832
#endregion
2933
}
3034

3135
public void Identity_ClientSideUserAuthentication_SimpleDeviceCode()
3236
{
3337
#region Snippet:Identity_ClientSideUserAuthentication_SimpleDeviceCode
38+
3439
var credential = new DeviceCodeCredential();
3540

3641
var client = new BlobClient(
3742
new Uri("https://myaccount.blob.core.windows.net/mycontainer/myblob"),
3843
credential
3944
);
45+
4046
#endregion
4147
}
4248

4349
public async Task Identity_ClientSideUserAuthentication_DisableAutomaticAuthentication()
4450
{
4551
#region Snippet:Identity_ClientSideUserAuthentication_DisableAutomaticAuthentication
52+
4653
var credential = new InteractiveBrowserCredential(
47-
new InteractiveBrowserCredentialOptions
48-
{
49-
DisableAutomaticAuthentication = true
50-
});
54+
new InteractiveBrowserCredentialOptions { DisableAutomaticAuthentication = true });
5155

5256
await credential.AuthenticateAsync();
5357

5458
var client = new SecretClient(new Uri("https://myvault.vault.azure.net/"), credential);
59+
5560
#endregion
5661

5762
#region Snippet:Identity_ClientSideUserAuthentication_DisableAutomaticAuthentication_ExHandling
63+
5864
try
5965
{
6066
client.GetSecret("secret");
@@ -67,6 +73,7 @@ public async Task Identity_ClientSideUserAuthentication_DisableAutomaticAuthenti
6773

6874
client.GetSecret("secret");
6975
}
76+
7077
#endregion
7178
}
7279

@@ -77,14 +84,14 @@ public static async Task<TokenCredential> GetUserCredentialAsync()
7784
if (!File.Exists(AUTH_RECORD_PATH))
7885
{
7986
#region Snippet:Identity_ClientSideUserAuthentication_Persist_TokenCache
87+
8088
var credential = new InteractiveBrowserCredential(
81-
new InteractiveBrowserCredentialOptions
82-
{
83-
TokenCachePersistenceOptions = new TokenCachePersistenceOptions()
84-
});
89+
new InteractiveBrowserCredentialOptions { TokenCachePersistenceOptions = new TokenCachePersistenceOptions() });
90+
8591
#endregion
8692

8793
#region Snippet:Identity_ClientSideUserAuthentication_Persist_AuthRecord
94+
8895
AuthenticationRecord authRecord = await credential.AuthenticateAsync();
8996

9097
using (var authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Create, FileAccess.Write))
@@ -99,6 +106,7 @@ public static async Task<TokenCredential> GetUserCredentialAsync()
99106
else
100107
{
101108
#region Snippet:Identity_ClientSideUserAuthentication_Persist_SilentAuth
109+
102110
AuthenticationRecord authRecord;
103111

104112
using (var authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Open, FileAccess.Read))
@@ -109,9 +117,9 @@ public static async Task<TokenCredential> GetUserCredentialAsync()
109117
var credential = new InteractiveBrowserCredential(
110118
new InteractiveBrowserCredentialOptions
111119
{
112-
TokenCachePersistenceOptions = new TokenCachePersistenceOptions(),
113-
AuthenticationRecord = authRecord
120+
TokenCachePersistenceOptions = new TokenCachePersistenceOptions(), AuthenticationRecord = authRecord
114121
});
122+
115123
#endregion
116124

117125
return credential;
@@ -120,41 +128,50 @@ public static async Task<TokenCredential> GetUserCredentialAsync()
120128

121129
public static async Task Main()
122130
{
131+
#region Snippet:AuthenticationRecord_TokenCachePersistenceOptions
132+
133+
const string TOKEN_CACHE_NAME = "MyTokenCache";
123134
InteractiveBrowserCredential credential;
135+
AuthenticationRecord authRecord;
124136

137+
// Check if an AuthenticationRecord exists on disk.
138+
// If it does not exist, get one and serialize it to disk.
139+
// If it does exist, load it from disk and deserialize it.
125140
if (!File.Exists(AUTH_RECORD_PATH))
126141
{
142+
// Construct a credential with TokenCachePersistenceOptions specified to ensure that the token cache is persisted to disk.
143+
// We can also optionally specify a name for the cache to avoid having it cleared by other applications.
127144
credential = new InteractiveBrowserCredential(
128-
new InteractiveBrowserCredentialOptions
129-
{
130-
TokenCachePersistenceOptions = new TokenCachePersistenceOptions()
131-
});
145+
new InteractiveBrowserCredentialOptions { TokenCachePersistenceOptions = new TokenCachePersistenceOptions { Name = TOKEN_CACHE_NAME } });
132146

133-
AuthenticationRecord authRecord = await credential.AuthenticateAsync();
147+
// Call AuthenticateAsync to fetch a new AuthenticationRecord.
148+
authRecord = await credential.AuthenticateAsync();
134149

135-
using (var authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Create, FileAccess.Write))
136-
{
137-
await authRecord.SerializeAsync(authRecordStream);
138-
}
150+
// Serialize the AuthenticationRecord to disk so that it can be re-used across executions of this initialization code.
151+
using var authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Create, FileAccess.Write);
152+
await authRecord.SerializeAsync(authRecordStream);
139153
}
140154
else
141155
{
142-
AuthenticationRecord authRecord;
143-
144-
using (var authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Open, FileAccess.Read))
145-
{
146-
authRecord = await AuthenticationRecord.DeserializeAsync(authRecordStream);
147-
}
156+
// Load the previously serialized AuthenticationRecord from disk and deserialize it.
157+
using var authRecordStream = new FileStream(AUTH_RECORD_PATH, FileMode.Open, FileAccess.Read);
158+
authRecord = await AuthenticationRecord.DeserializeAsync(authRecordStream);
148159

160+
// Construct a new client with our TokenCachePersistenceOptions with the addition of the AuthenticationRecord property.
161+
// This tells the credential to use the same token cache in addition to which account to try and fetch from cache when GetToken is called.
149162
credential = new InteractiveBrowserCredential(
150163
new InteractiveBrowserCredentialOptions
151164
{
152-
TokenCachePersistenceOptions = new TokenCachePersistenceOptions(),
165+
TokenCachePersistenceOptions = new TokenCachePersistenceOptions { Name = TOKEN_CACHE_NAME },
153166
AuthenticationRecord = authRecord
154167
});
155168
}
156169

170+
// Construct our client with the credential which is connected to the token cache
171+
// with the capability of silent authentication for the account specified in the AuthenticationRecord.
157172
var client = new SecretClient(new Uri("https://myvault.vault.azure.net/"), credential);
173+
174+
#endregion
158175
}
159176
}
160177
}

0 commit comments

Comments
 (0)