1
1
//<Snippet1>
2
2
using System ;
3
+ using System . Collections . Generic ;
4
+ using System . Linq ;
3
5
using System . Threading . Tasks ;
4
- using Microsoft . Identity . Client ;
5
6
using Microsoft . Data . SqlClient ;
7
+ using Microsoft . Identity . Client ;
6
8
7
9
namespace CustomAuthenticationProviderExamples
8
10
{
@@ -12,28 +14,46 @@ namespace CustomAuthenticationProviderExamples
12
14
/// </summary>
13
15
public class CustomDeviceCodeFlowAzureAuthenticationProvider : SqlAuthenticationProvider
14
16
{
17
+ private const string clientId = "my-client-id" ;
18
+ private const string clientName = "My Application Name" ;
19
+ private const string s_defaultScopeSuffix = "/.default" ;
20
+
21
+ // Maintain a copy of the PublicClientApplication object to cache the underlying access tokens it provides
22
+ private static IPublicClientApplication pcApplication ;
23
+
15
24
public override async Task < SqlAuthenticationToken > AcquireTokenAsync ( SqlAuthenticationParameters parameters )
16
25
{
17
- string clientId = "my-client-id" ;
18
- string clientName = "My Application Name" ;
19
- string s_defaultScopeSuffix = "/.default" ;
20
-
21
26
string [ ] scopes = new string [ ] { parameters . Resource . EndsWith ( s_defaultScopeSuffix ) ? parameters . Resource : parameters . Resource + s_defaultScopeSuffix } ;
22
27
23
- IPublicClientApplication app = PublicClientApplicationBuilder . Create ( clientId )
24
- . WithAuthority ( parameters . Authority )
25
- . WithClientName ( clientName )
26
- . WithRedirectUri ( "https://login.microsoftonline.com/common/oauth2/nativeclient" )
28
+ IPublicClientApplication app = pcApplication ;
29
+ if ( app == null )
30
+ {
31
+ pcApplication = app = PublicClientApplicationBuilder . Create ( clientId )
32
+ . WithAuthority ( parameters . Authority )
33
+ . WithClientName ( clientName )
34
+ . WithRedirectUri ( "https://login.microsoftonline.com/common/oauth2/nativeclient" )
27
35
. Build ( ) ;
36
+ }
37
+
38
+ AuthenticationResult result ;
39
+
40
+ try
41
+ {
42
+ IEnumerable < IAccount > accounts = await app . GetAccountsAsync ( ) ;
43
+ result = await app . AcquireTokenSilent ( scopes , accounts . FirstOrDefault ( ) ) . ExecuteAsync ( ) ;
44
+ }
45
+ catch ( MsalUiRequiredException )
46
+ {
47
+ result = await app . AcquireTokenWithDeviceCode ( scopes ,
48
+ deviceCodeResult => CustomDeviceFlowCallback ( deviceCodeResult ) ) . ExecuteAsync ( ) ;
49
+ }
28
50
29
- AuthenticationResult result = await app . AcquireTokenWithDeviceCode ( scopes ,
30
- deviceCodeResult => CustomDeviceFlowCallback ( deviceCodeResult ) ) . ExecuteAsync ( ) ;
31
51
return new SqlAuthenticationToken ( result . AccessToken , result . ExpiresOn ) ;
32
52
}
33
53
34
54
public override bool IsSupported ( SqlAuthenticationMethod authenticationMethod ) => authenticationMethod . Equals ( SqlAuthenticationMethod . ActiveDirectoryDeviceCodeFlow ) ;
35
55
36
- private Task CustomDeviceFlowCallback ( DeviceCodeResult result )
56
+ private static Task < int > CustomDeviceFlowCallback ( DeviceCodeResult result )
37
57
{
38
58
Console . WriteLine ( result . Message ) ;
39
59
return Task . FromResult ( 0 ) ;
0 commit comments