Skip to content

Commit b7629bf

Browse files
committed
Update to MSAL
1 parent 29f4c75 commit b7629bf

File tree

7 files changed

+67
-65
lines changed

7 files changed

+67
-65
lines changed

TodoListClient/App.config

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
55
</startup>
66
<appSettings>
7-
<add key="ida:AADInstance" value="https://login.microsoftonline.com/{0}" />
87
<add key="ida:ClientId" value="{Enter the Application Id that you copied from the App Registration Portal.}" />
9-
<add key="ida:RedirectUri" value="{Enter the Redirect Uri copied from the App Registration Portal.}" />
108
<add key="todo:TodoListBaseAddress" value="https://localhost:44321/" />
119
</appSettings>
1210
</configuration>

TodoListClient/FileCache.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory;
1+
using Microsoft.Identity.Client;
22
using System;
33
using System.Collections.Generic;
44
using System.IO;
@@ -18,7 +18,7 @@ class FileCache : TokenCache
1818
private static readonly object FileLock = new object();
1919

2020
// Initializes the cache against a local file.
21-
// If the file is already rpesent, it loads its content in the ADAL cache
21+
// If the file is already present, it loads its content in the MSAL cache
2222
public FileCache(string filePath=@".\TokenCache.dat")
2323
{
2424
CacheFilePath = filePath;
@@ -31,13 +31,13 @@ public FileCache(string filePath=@".\TokenCache.dat")
3131
}
3232

3333
// Empties the persistent store.
34-
public override void Clear()
34+
public override void Clear(string clientId)
3535
{
36-
base.Clear();
36+
base.Clear(clientId);
3737
File.Delete(CacheFilePath);
3838
}
3939

40-
// Triggered right before ADAL needs to access the cache.
40+
// Triggered right before MSAL needs to access the cache.
4141
// Reload the cache from the persistent store in case it changed since the last access.
4242
void BeforeAccessNotification(TokenCacheNotificationArgs args)
4343
{
@@ -47,7 +47,7 @@ void BeforeAccessNotification(TokenCacheNotificationArgs args)
4747
}
4848
}
4949

50-
// Triggered right after ADAL accessed the cache.
50+
// Triggered right after MSAL accessed the cache.
5151
void AfterAccessNotification(TokenCacheNotificationArgs args)
5252
{
5353
// if the access operation resulted in a cache update

TodoListClient/MainWindow.xaml.cs

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@
3131

3232
// The following using statements were added for this sample.
3333
using System.Globalization;
34-
using Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory;
34+
using Microsoft.Identity.Client;
3535
using System.Net.Http;
3636
using System.Net.Http.Headers;
3737
using System.Web.Script.Serialization;
3838
using System.Runtime.InteropServices;
3939
using System.Configuration;
40-
using Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory;
40+
4141

4242
namespace TodoListClient
4343
{
@@ -52,49 +52,49 @@ public partial class MainWindow : Window
5252
// The Redirect URI is the URI where the v2.0 endpoint will return OAuth responses.
5353
// The Authority is the sign-in URL.
5454

55-
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
55+
5656
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
57-
Uri redirectUri = new Uri(ConfigurationManager.AppSettings["ida:RedirectUri"]);
58-
private static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, "common");
57+
5958
private static string todoListBaseAddress = ConfigurationManager.AppSettings["todo:TodoListBaseAddress"];
6059

6160
private HttpClient httpClient = new HttpClient();
62-
private AuthenticationContext authContext = null;
61+
private PublicClientApplication app = null;
6362

6463
protected override async void OnInitialized(EventArgs e)
6564
{
6665
base.OnInitialized(e);
6766

68-
authContext = new AuthenticationContext(authority, new FileCache());
67+
// TODO: Initialize the PublicClientApplication
68+
app = new PublicClientApplication(clientId)
69+
{
70+
UserTokenCache = new FileCache(),
71+
};
6972
AuthenticationResult result = null;
7073

74+
// TODO: Check if the user is already signed in.
7175
// As the app starts, we want to check to see if the user is already signed in.
72-
// You can do so by trying to get a token from ADAL, passing in the parameter
73-
// PromptBehavior.Never. This forces ADAL to throw an exception if it cannot
76+
// You can do so by trying to get a token from MSAL, using the method
77+
// AcquireTokenSilent. This forces MSAL to throw an exception if it cannot
7478
// get a token for the user without showing a UI.
75-
7679
try
7780
{
78-
result = await authContext.AcquireTokenAsync(new string[] { clientId }, null, clientId, redirectUri, new PlatformParameters(PromptBehavior.Never, null));
79-
80-
// If we got here, a valid token is in the cache. Proceed to
81-
// fetch the user's tasks from the TodoListService via the
82-
// GetTodoList() method.
83-
81+
result = await app.AcquireTokenSilentAsync(new string[] { clientId });
82+
// If we got here, a valid token is in the cache - or MSAL was able to get a new oen via refresh token.
83+
// Proceed to fetch the user's tasks from the TodoListService via the GetTodoList() method.
84+
8485
SignInButton.Content = "Clear Cache";
8586
GetTodoList();
8687
}
87-
catch (AdalException ex)
88+
catch (MsalException ex)
8889
{
89-
if (ex.ErrorCode == "user_interaction_required")
90+
if (ex.ErrorCode == "failed_to_acquire_token_silently")
9091
{
9192
// If user interaction is required, the app should take no action,
9293
// and simply show the user the sign in button.
9394
}
9495
else
9596
{
96-
// Here, we catch all other AdalExceptions
97-
97+
// Here, we catch all other MsalExceptions
9898
string message = ex.Message;
9999
if (ex.InnerException != null)
100100
{
@@ -104,7 +104,7 @@ protected override async void OnInitialized(EventArgs e)
104104
}
105105
}
106106
}
107-
107+
108108

109109
public MainWindow()
110110
{
@@ -113,21 +113,26 @@ public MainWindow()
113113

114114
private async void GetTodoList()
115115
{
116+
117+
// TODO: Get a token from MSAL, and attach
118+
// it to the GET request in the Authorization
119+
// header.
120+
116121
AuthenticationResult result = null;
117122
try
118123
{
119-
// Here, we try to get an access token to call the TodoListService
120-
// without invoking any UI prompt. PromptBehavior.Never forces
121-
// ADAL to throw an exception if it cannot get a token silently.
124+
// Here, we try to get an access token to call the TodoListService
125+
// without invoking any UI prompt. AcquireTokenSilentAsync forces
126+
// MSAL to throw an exception if it cannot get a token silently.
122127

123-
result = await authContext.AcquireTokenAsync(new string[] { clientId }, null, clientId, redirectUri, new PlatformParameters(PromptBehavior.Never, null));
128+
result = await app.AcquireTokenSilentAsync(new string[] { clientId });
124129
}
125-
catch (AdalException ex)
130+
catch (MsalException ex)
126131
{
127-
// ADAL couldn't get a token silently, so show the user a message
132+
// MSAL couldn't get a token silently, so show the user a message
128133
// and let them click the Sign-In button.
129134

130-
if (ex.ErrorCode == "user_interaction_required")
135+
if (ex.ErrorCode == "failed_to_acquire_token_silently")
131136
{
132137
MessageBox.Show("Please sign in first");
133138
SignInButton.Content = "Sign In";
@@ -147,13 +152,12 @@ private async void GetTodoList()
147152
return;
148153
}
149154

150-
// Once the token has been returned by ADAL,
151-
// add it to the http authorization header,
155+
// Once the token has been returned by MSAL,
156+
// add it to the http authorization header,
152157
// before making the call to access the To Do list service.
153158

154159
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.Token);
155160

156-
157161
// Call the To Do list service.
158162
HttpResponseMessage response = await httpClient.GetAsync(todoListBaseAddress + "/api/todolist");
159163

@@ -185,11 +189,11 @@ private async void AddTodoItem(object sender, RoutedEventArgs e)
185189
AuthenticationResult result = null;
186190
try
187191
{
188-
result = await authContext.AcquireTokenAsync(new string[] { clientId }, null, clientId, redirectUri, new PlatformParameters(PromptBehavior.Never, null));
192+
result = await app.AcquireTokenSilentAsync(new string[] { clientId });
189193
}
190-
catch (AdalException ex)
194+
catch (MsalException ex)
191195
{
192-
if (ex.ErrorCode == "user_interaction_required")
196+
if (ex.ErrorCode == "failed_to_acquire_token_silently")
193197
{
194198
MessageBox.Show("Please sign in first");
195199
SignInButton.Content = "Sign In";
@@ -226,36 +230,38 @@ private async void AddTodoItem(object sender, RoutedEventArgs e)
226230

227231
private async void SignIn(object sender = null, RoutedEventArgs args = null)
228232
{
233+
// TODO: Sign the user out if they clicked the "Clear Cache" button
234+
229235
// If the user clicked the 'clear cache' button,
230-
// clear the ADAL token cache and show the user as signed out.
236+
// clear the MSAL token cache and show the user as signed out.
231237
// It's also necessary to clear the cookies from the browser
232238
// control so the next user has a chance to sign in.
233239

234240
if (SignInButton.Content.ToString() == "Clear Cache")
235241
{
236242
TodoList.ItemsSource = string.Empty;
237-
authContext.TokenCache.Clear();
243+
app.UserTokenCache.Clear(app.ClientId);
238244
ClearCookies();
239245
SignInButton.Content = "Sign In";
240246
return;
241247
}
242248

243249
// If the user clicked the 'Sign-In' button, force
244-
// ADAL to prompt the user for credentials by specifying
245-
// PromptBehavior.Always. ADAL will get a token for the
246-
// TodoListService and cache it for you.
250+
// MSAL to prompt the user for credentials by using
251+
// AcquireTokenAsync, a method that is guaranteed to show a prompt to the user.
252+
// MSAL will get a token for the TodoListService and cache it for you.
247253

248254
AuthenticationResult result = null;
249255
try
250256
{
251-
result = await authContext.AcquireTokenAsync(new string[] { clientId }, null, clientId, redirectUri, new PlatformParameters(PromptBehavior.Always, null));
257+
result = await app.AcquireTokenAsync(new string[] { clientId });
252258
SignInButton.Content = "Clear Cache";
253259
GetTodoList();
254260
}
255-
catch (AdalException ex)
261+
catch (MsalException ex)
256262
{
257-
// If ADAL cannot get a token, it will throw an exception.
258-
// If the user canceled the login, it will result in the
263+
// If MSAL cannot get a token, it will throw an exception.
264+
// If the user canceled the login, it will result in the
259265
// error code 'authentication_canceled'.
260266

261267
if (ex.ErrorCode == "authentication_canceled")
@@ -277,9 +283,12 @@ private async void SignIn(object sender = null, RoutedEventArgs args = null)
277283
return;
278284
}
279285

286+
287+
// TODO: Invoke UI & get a token if the user clicked "Sign In"
288+
280289
}
281290

282-
// This function clears cookies from the browser control used by ADAL.
291+
// This function clears cookies from the browser control used by MSAL.
283292
private void ClearCookies()
284293
{
285294
const int INTERNET_OPTION_END_BROWSER_SESSION = 42;

TodoListClient/TodoListClient.csproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@
3434
<WarningLevel>4</WarningLevel>
3535
</PropertyGroup>
3636
<ItemGroup>
37-
<Reference Include="Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
38-
<SpecificVersion>False</SpecificVersion>
39-
<HintPath>..\packages\Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory.4.0.208052020-alpha\lib\net45\Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
37+
<Reference Include="Microsoft.Identity.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
38+
<HintPath>..\packages\Microsoft.Identity.Client.1.0.304142221-alpha\lib\net45\Microsoft.Identity.Client.dll</HintPath>
39+
<Private>True</Private>
4040
</Reference>
41-
<Reference Include="Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory.Platform, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
42-
<SpecificVersion>False</SpecificVersion>
43-
<HintPath>..\packages\Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory.4.0.208052020-alpha\lib\net45\Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
41+
<Reference Include="Microsoft.Identity.Client.Platform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
42+
<HintPath>..\packages\Microsoft.Identity.Client.1.0.304142221-alpha\lib\net45\Microsoft.Identity.Client.Platform.dll</HintPath>
43+
<Private>True</Private>
4444
</Reference>
4545
<Reference Include="System" />
4646
<Reference Include="System.Configuration" />

TodoListClient/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3-
<package id="Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory" version="4.0.208052020-alpha" targetFramework="net45" />
3+
<package id="Microsoft.Identity.Client" version="1.0.304142221-alpha" targetFramework="net45" />
44
</packages>

TodoListService/App_Start/Startup.Auth.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ public void ConfigureAuth(IAppBuilder app)
2424
ValidateIssuer = false,
2525
};
2626

27-
// NOTE: The usual WindowsAzureActiveDirectoryBearerAuthenticaitonMiddleware uses a
28-
// metadata endpoint which is not supported by the v2.0 endpoint. Instead, this
29-
// OpenIdConenctCachingSecurityTokenProvider can be used to fetch & use the OpenIdConnect
30-
// metadata document.
31-
3227
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
3328
{
3429
AccessTokenFormat = new Microsoft.Owin.Security.Jwt.JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider("https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration")),

TodoListService/Web.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<add key="webpages:Enabled" value="false" />
1010
<add key="ClientValidationEnabled" value="true" />
1111
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
12-
<add key="ida:Audience" value="{Enter the Application Id that you copied from the App Registration Portal.}" />
12+
<add key="ida:Audience" value="{Enter the Application Id that you copied from the App Registration Portal.}" />
1313
</appSettings>
1414
<system.web>
1515
<compilation debug="true" targetFramework="4.5" />

0 commit comments

Comments
 (0)