44 */
55package com .microsoft .sqlserver .jdbc .fedauth ;
66
7- import static org .junit .jupiter . api . Assertions .assertTrue ;
7+ import static org .junit .Assert .assertTrue ;
88import static org .junit .jupiter .api .Assertions .fail ;
99
10- import com .microsoft .aad .msal4j .ClientCredentialFactory ;
11- import com .microsoft .aad .msal4j .ClientCredentialParameters ;
12- import com .microsoft .aad .msal4j .ConfidentialClientApplication ;
1310import com .microsoft .aad .msal4j .IAuthenticationResult ;
14- import com .microsoft .aad .msal4j .IClientCredential ;
15- import com .microsoft .aad .msal4j .ITokenCacheAccessAspect ;
16- import com .microsoft .aad .msal4j .ITokenCacheAccessContext ;
1711import com .microsoft .aad .msal4j .MsalThrottlingException ;
18-
12+ import com .microsoft .aad .msal4j .PublicClientApplication ;
13+ import com .microsoft .aad .msal4j .UserNamePasswordParameters ;
1914import java .sql .Connection ;
2015import java .sql .PreparedStatement ;
2116import java .sql .ResultSet ;
2217import java .sql .SQLException ;
2318import java .sql .Statement ;
19+ import java .util .Collections ;
2420import java .util .Date ;
25- import java .util .HashSet ;
2621import java .util .Locale ;
27- import java .util .Set ;
2822import java .util .concurrent .CompletableFuture ;
2923import java .util .concurrent .Executors ;
3024import java .util .concurrent .TimeUnit ;
31- import java .util .concurrent .locks .Lock ;
32- import java .util .concurrent .locks .ReentrantLock ;
3325import java .util .logging .LogManager ;
3426
3527import org .junit .jupiter .api .BeforeAll ;
4234import com .microsoft .sqlserver .testframework .AbstractTest ;
4335
4436
45- @ Tag (Constants .fedAuth )
46- class FedauthTokenCache implements ITokenCacheAccessAspect {
47- private static FedauthTokenCache instance = new FedauthTokenCache ();
48- private final Lock lock = new ReentrantLock ();
49-
50- private FedauthTokenCache () {}
51-
52- static FedauthTokenCache getInstance () {
53- return instance ;
54- }
55-
56- private String cache = null ;
57-
58- @ Override
59- public void beforeCacheAccess (ITokenCacheAccessContext iTokenCacheAccessContext ) {
60- lock .lock ();
61- try {
62- if (null != cache && null != iTokenCacheAccessContext && null != iTokenCacheAccessContext .tokenCache ()) {
63- iTokenCacheAccessContext .tokenCache ().deserialize (cache );
64- }
65- } finally {
66- lock .unlock ();
67- }
68- }
69-
70- @ Override
71- public void afterCacheAccess (ITokenCacheAccessContext iTokenCacheAccessContext ) {
72- lock .lock ();
73- try {
74- if (null != iTokenCacheAccessContext && iTokenCacheAccessContext .hasCacheChanged ()
75- && null != iTokenCacheAccessContext .tokenCache ())
76- cache = iTokenCacheAccessContext .tokenCache ().serialize ();
77- } finally {
78- lock .unlock ();
79- }
80- }
81-
82- static void clearUserTokenCache () {
83- if (null != instance .cache && !instance .cache .isEmpty ()) {
84- instance .cache = null ;
85- }
86- }
87- }
88-
89-
9037@ Tag (Constants .fedAuth )
9138public class FedauthCommon extends AbstractTest {
9239
@@ -95,6 +42,8 @@ public class FedauthCommon extends AbstractTest {
9542 static String azureUserName = null ;
9643 static String azurePassword = null ;
9744 static String azureGroupUserName = null ;
45+ static String azureAADPrincipalId = null ;
46+ static String azureAADPrincipalSecret = null ;
9847
9948 static boolean enableADIntegrated = false ;
10049
@@ -106,7 +55,6 @@ public class FedauthCommon extends AbstractTest {
10655 static String fedauthClientId = null ;
10756 static long secondsBeforeExpiration = -1 ;
10857 static String accessToken = null ;
109- static String certificatePassword = null ;
11058 static String [] fedauthJksPaths = null ;
11159 static String [] fedauthJksPathsLinux = null ;
11260 static String [] fedauthJavaKeyAliases = null ;
@@ -127,8 +75,6 @@ public class FedauthCommon extends AbstractTest {
12775 static final String ERR_MSG_HAS_CLOSED = TestResource .getResource ("R_hasClosed" );
12876 static final String ERR_MSG_HAS_BEEN_CLOSED = TestResource .getResource ("R_hasBeenClosed" );
12977 static final String ERR_MSG_SIGNIN_TOO_MANY = TestResource .getResource ("R_signinTooManyTimes" );
130- static final String ERR_FAULT_ID3342 = "FaultMessage: ID3242" ;
131- static final String ERR_FAULT_AUTH_FAIL = "FaultMessage: Authentication Failure" ;
13278 static final String ERR_MSG_NOT_AUTH_AND_IS = TestUtils .R_BUNDLE
13379 .getString ("R_SetAuthenticationWhenIntegratedSecurityTrue" );
13480 static final String ERR_MSG_NOT_AUTH_AND_USER_PASSWORD = TestUtils .R_BUNDLE
@@ -145,8 +91,7 @@ enum SqlAuthentication {
14591 SqlPassword ,
14692 ActiveDirectoryPassword ,
14793 ActiveDirectoryIntegrated ,
148- ActiveDirectoryServicePrincipal ,
149- ActiveDirectoryServicePrincipalCertificate ;
94+ ActiveDirectoryServicePrincipal ;
15095
15196 static SqlAuthentication valueOfString (String value ) throws SQLServerException {
15297 SqlAuthentication method = null ;
@@ -179,9 +124,8 @@ public static void getConfigs() throws Exception {
179124 azureUserName = getConfiguredProperty ("azureUserName" );
180125 azurePassword = getConfiguredProperty ("azurePassword" );
181126 azureGroupUserName = getConfiguredProperty ("azureGroupUserName" );
182-
183- // password for service principal certificate
184- certificatePassword = getConfiguredProperty ("certificatePassword" );
127+ azureAADPrincipalId = getConfiguredProperty ("AADSecurePrincipalId" );
128+ azureAADPrincipalSecret = getConfiguredProperty ("AADSecurePrincipalSecret" );
185129
186130 String prop = getConfiguredProperty ("enableADIntegrated" );
187131 enableADIntegrated = (null != prop && prop .equalsIgnoreCase ("true" )) ? true : false ;
@@ -218,34 +162,30 @@ static void getFedauthInfo() {
218162 long interval = THROTTLE_RETRY_INTERVAL ;
219163 while (retry <= THROTTLE_RETRY_COUNT ) {
220164 try {
221- Set <String > scopes = new HashSet <>();
222- scopes .add (spn + "/.default" );
223- if (null == fedauthClientApp ) {
224- IClientCredential credential = ClientCredentialFactory .createFromSecret (applicationKey );
225- fedauthClientApp = ConfidentialClientApplication .builder (applicationClientID , credential )
226- .executorService (Executors .newFixedThreadPool (1 ))
227- .setTokenCacheAccessAspect (FedauthTokenCache .getInstance ()).authority (stsurl ).build ();
165+ if (null == fedauthPcaApp ) {
166+ fedauthPcaApp = PublicClientApplication .builder (fedauthClientId )
167+ .executorService (Executors .newFixedThreadPool (1 )).authority (stsurl ).build ();
228168 }
229169
230- final CompletableFuture <IAuthenticationResult > future = fedauthClientApp
231- .acquireToken (ClientCredentialParameters .builder (scopes ).build ());
170+ final CompletableFuture <IAuthenticationResult > future = fedauthPcaApp
171+ .acquireToken (UserNamePasswordParameters .builder (Collections .singleton (spn + "/.default" ),
172+ azureUserName , azurePassword .toCharArray ()).build ());
232173
233174 final IAuthenticationResult authenticationResult = future .get ();
234175
235176 secondsBeforeExpiration = TimeUnit .MILLISECONDS
236177 .toSeconds (authenticationResult .expiresOnDate ().getTime () - new Date ().getTime ());
237178 accessToken = authenticationResult .accessToken ();
238-
239179 retry = THROTTLE_RETRY_COUNT + 1 ;
240180 } catch (MsalThrottlingException te ) {
241181 interval = te .retryInMs ();
242182 if (!checkForRetry (te , retry ++, interval )) {
243- te .printStackTrace ();
244183 fail (ERR_FAILED_FEDAUTH + "no more retries: " + te .getMessage ());
245184 }
246185 } catch (Exception e ) {
247- e .printStackTrace ();
248- fail (ERR_FAILED_FEDAUTH + e .getMessage ());
186+ if (!checkForRetry (e , retry ++, interval )) {
187+ fail (ERR_FAILED_FEDAUTH + "no more retries: " + e .getMessage ());
188+ }
249189 }
250190 }
251191 }
@@ -255,6 +195,8 @@ static boolean checkForRetry(Exception e, int retry, long interval) {
255195 return false ;
256196 }
257197 try {
198+ System .out
199+ .println (e .getMessage () + "Get FedAuth token failed, retry #" + retry + " in " + interval + " ms" );
258200 Thread .sleep (interval );
259201 } catch (InterruptedException ex ) {
260202 e .printStackTrace ();
@@ -267,12 +209,11 @@ static boolean checkForRetry(Exception e, int retry, long interval) {
267209 void testUserName (Connection conn , String user , SqlAuthentication authentication ) throws SQLException {
268210 try (Statement stmt = conn .createStatement (); ResultSet rs = stmt .executeQuery ("SELECT SUSER_SNAME()" )) {
269211 rs .next ();
270- if (SqlAuthentication .ActiveDirectoryPassword == authentication
271- || SqlAuthentication .SqlPassword == authentication ) {
272- assertTrue (user .equals (rs .getString (1 )), rs .getString (1 ));
273- } else if (SqlAuthentication .ActiveDirectoryIntegrated == authentication ) {
212+ if (SqlAuthentication .ActiveDirectoryIntegrated != authentication ) {
213+ assertTrue (user .equals (rs .getString (1 )));
214+ } else {
274215 if (isWindows ) {
275- assertTrue (rs .getString (1 ).contains (System .getProperty ("user.name" )), rs . getString ( 1 ) );
216+ assertTrue (rs .getString (1 ).contains (System .getProperty ("user.name" )));
276217 } else {
277218 // cannot verify user in kerberos tickets so just check it's not empty
278219 assertTrue (!rs .getString (1 ).isEmpty ());
0 commit comments