This repository has been archived by the owner on Sep 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 32
/
ExampleUsage.cs
148 lines (121 loc) · 5.66 KB
/
ExampleUsage.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using Microsoft.Identity.Client.Extensions.Msal;
namespace ManualTestApp
{
/// <summary>
/// This class shows how to applications are supposed to use the extension API
/// </summary>
public class ExampleUsage
{
private const string TraceSourceName = "MSAL.Contoso.CacheExtension";
/// <summary>
/// Start reading here...
/// </summary>
public static async Task Example_Async()
{
// 1. Use MSAL to create an instance of the Public Client Application
var app = PublicClientApplicationBuilder.Create(Config.ClientId).Build();
// 2. Configure the storage
var cacheHelper = await CreateCacheHelperAsync().ConfigureAwait(false);
// 3. Let the cache helper handle MSAL's cache
cacheHelper.RegisterCache(app.UserTokenCache);
// 4. Optionally, store some other secret
StoreOtherSecret();
}
private static async Task<MsalCacheHelper> CreateCacheHelperAsync()
{
StorageCreationProperties storageProperties;
MsalCacheHelper cacheHelper;
try
{
storageProperties = ConfigureSecureStorage(usePlaintextFileOnLinux: false);
cacheHelper = await MsalCacheHelper.CreateAsync(
storageProperties,
new TraceSource(TraceSourceName))
.ConfigureAwait(false);
// the underlying persistence mechanism might not be usable
// this typically happens on Linux over SSH
cacheHelper.VerifyPersistence();
return cacheHelper;
}
catch (MsalCachePersistenceException ex)
{
Console.WriteLine("Cannot persist data securely. ");
Console.WriteLine("Details: " + ex);
if (SharedUtilities.IsLinuxPlatform())
{
storageProperties = ConfigureSecureStorage(usePlaintextFileOnLinux: true);
Console.WriteLine($"Falling back on using a plaintext " +
$"file located at {storageProperties.CacheFilePath} Users are responsible for securing this file!");
cacheHelper = await MsalCacheHelper.CreateAsync(
storageProperties,
new TraceSource(TraceSourceName))
.ConfigureAwait(false);
return cacheHelper;
}
throw;
}
}
private static StorageCreationProperties ConfigureSecureStorage(bool usePlaintextFileOnLinux)
{
if (!usePlaintextFileOnLinux)
{
return new StorageCreationPropertiesBuilder(
Config.CacheFileName,
Config.CacheDir)
.WithLinuxKeyring(
Config.LinuxKeyRingSchema,
Config.LinuxKeyRingCollection,
Config.LinuxKeyRingLabel,
Config.LinuxKeyRingAttr1,
Config.LinuxKeyRingAttr2)
.WithMacKeyChain(
Config.KeyChainServiceName,
Config.KeyChainAccountName)
.Build();
}
return new StorageCreationPropertiesBuilder(
Config.CacheFileName + "plaintext", // do not use the same file name so as not to overwrite the encypted version
Config.CacheDir)
.WithLinuxUnprotectedFile()
.WithMacKeyChain(
Config.KeyChainServiceName,
Config.KeyChainAccountName)
.Build();
}
private static void StoreOtherSecret()
{
var storageProperties = new StorageCreationPropertiesBuilder(
Config.CacheFileName + ".other_secrets",
Config.CacheDir)
.WithMacKeyChain(
Config.KeyChainServiceName + ".other_secrets",
Config.KeyChainAccountName)
.WithLinuxKeyring(
Config.LinuxKeyRingSchema,
Config.LinuxKeyRingCollection,
Config.LinuxKeyRingLabel,
Config.LinuxKeyRingAttr1,
new KeyValuePair<string, string>("other_secrets", "secret_description"));
Storage storage = Storage.Create(storageProperties.Build());
byte[] secretBytes = Encoding.UTF8.GetBytes("secret");
using (new CrossPlatLock(Config.CacheFileName + ".other_secrets.lock"))
{
Console.WriteLine("Writing...");
storage.WriteData(secretBytes);
Console.WriteLine("Writing again...");
storage.WriteData(secretBytes);
Console.WriteLine("Reading...");
var data = storage.ReadData();
Console.WriteLine("Read: " + Encoding.UTF8.GetString(data));
Console.WriteLine("Deleting...");
storage.Clear();
}
}
}
}