Skip to content

Commit dfb4b77

Browse files
tkycJeffery-Wasty
authored andcommitted
Updated fedauth error tests (#2538)
Signed-off-by: Jeff Wasty <[email protected]> # Conflicts: # src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java # src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java
1 parent 9173ac9 commit dfb4b77

File tree

2 files changed

+92
-27
lines changed

2 files changed

+92
-27
lines changed

src/test/java/com/microsoft/sqlserver/jdbc/fedauth/ErrorMessageTest.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,9 @@ public void testADPasswordWrongPasswordWithConnectionStringUserName() throws SQL
396396
+ " in Active Directory (Authentication=ActiveDirectoryPassword).")
397397
&& e.getCause().getCause().getMessage().toLowerCase().contains("invalid username or password")
398398
|| e.getCause().getCause().getMessage().contains(ERR_MSG_SIGNIN_TOO_MANY)
399-
|| e.getMessage().contains(ERR_MSG_REQUEST_THROTTLED));
399+
|| e.getCause().getCause().getMessage().contains(ERR_FAULT_ID3342)
400+
|| e.getMessage().contains(ERR_MSG_REQUEST_THROTTLED)
401+
|| e.getMessage().contains(ERR_FAULT_AUTH_FAIL));
400402
}
401403
}
402404

@@ -422,7 +424,9 @@ public void testADPasswordWrongPasswordWithDatasource() throws SQLException {
422424
+ " in Active Directory (Authentication=ActiveDirectoryPassword).")
423425
&& e.getCause().getCause().getMessage().toLowerCase().contains("invalid username or password")
424426
|| e.getCause().getCause().getMessage().contains(ERR_MSG_SIGNIN_TOO_MANY)
425-
|| e.getMessage().contains(ERR_MSG_REQUEST_THROTTLED));
427+
|| e.getCause().getCause().getMessage().contains(ERR_FAULT_ID3342)
428+
|| e.getMessage().contains(ERR_MSG_REQUEST_THROTTLED)
429+
|| e.getMessage().contains(ERR_FAULT_AUTH_FAIL));
426430
}
427431
}
428432

@@ -442,7 +446,9 @@ public void testADPasswordWrongPasswordWithConnectionStringUser() throws SQLExce
442446
+ " in Active Directory (Authentication=ActiveDirectoryPassword).")
443447
&& e.getCause().getCause().getMessage().toLowerCase().contains("invalid username or password")
444448
|| e.getCause().getCause().getMessage().contains(ERR_MSG_SIGNIN_TOO_MANY)
445-
|| e.getMessage().contains(ERR_MSG_REQUEST_THROTTLED));
449+
|| e.getCause().getCause().getMessage().contains(ERR_FAULT_ID3342)
450+
|| e.getMessage().contains(ERR_MSG_REQUEST_THROTTLED)
451+
|| e.getMessage().contains(ERR_FAULT_AUTH_FAIL));
446452
}
447453
}
448454

src/test/java/com/microsoft/sqlserver/jdbc/fedauth/FedauthCommon.java

Lines changed: 83 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,32 @@
44
*/
55
package com.microsoft.sqlserver.jdbc.fedauth;
66

7-
import static org.junit.Assert.assertTrue;
7+
import static org.junit.jupiter.api.Assertions.assertTrue;
88
import 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;
1013
import 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;
1117
import com.microsoft.aad.msal4j.MsalThrottlingException;
12-
import com.microsoft.aad.msal4j.PublicClientApplication;
13-
import com.microsoft.aad.msal4j.UserNamePasswordParameters;
18+
1419
import java.sql.Connection;
1520
import java.sql.PreparedStatement;
1621
import java.sql.ResultSet;
1722
import java.sql.SQLException;
1823
import java.sql.Statement;
19-
import java.util.Collections;
2024
import java.util.Date;
25+
import java.util.HashSet;
2126
import java.util.Locale;
27+
import java.util.Set;
2228
import java.util.concurrent.CompletableFuture;
2329
import java.util.concurrent.Executors;
2430
import java.util.concurrent.TimeUnit;
31+
import java.util.concurrent.locks.Lock;
32+
import java.util.concurrent.locks.ReentrantLock;
2533
import java.util.logging.LogManager;
2634

2735
import org.junit.jupiter.api.BeforeAll;
@@ -34,6 +42,51 @@
3442
import com.microsoft.sqlserver.testframework.AbstractTest;
3543

3644

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+
3790
@Tag(Constants.fedAuth)
3891
public class FedauthCommon extends AbstractTest {
3992

@@ -42,8 +95,6 @@ public class FedauthCommon extends AbstractTest {
4295
static String azureUserName = null;
4396
static String azurePassword = null;
4497
static String azureGroupUserName = null;
45-
static String azureAADPrincipalId = null;
46-
static String azureAADPrincipalSecret = null;
4798

4899
static boolean enableADIntegrated = false;
49100

@@ -55,6 +106,7 @@ public class FedauthCommon extends AbstractTest {
55106
static String fedauthClientId = null;
56107
static long secondsBeforeExpiration = -1;
57108
static String accessToken = null;
109+
static String certificatePassword = null;
58110
static String[] fedauthJksPaths = null;
59111
static String[] fedauthJksPathsLinux = null;
60112
static String[] fedauthJavaKeyAliases = null;
@@ -75,6 +127,8 @@ public class FedauthCommon extends AbstractTest {
75127
static final String ERR_MSG_HAS_CLOSED = TestResource.getResource("R_hasClosed");
76128
static final String ERR_MSG_HAS_BEEN_CLOSED = TestResource.getResource("R_hasBeenClosed");
77129
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";
78132
static final String ERR_MSG_NOT_AUTH_AND_IS = TestUtils.R_BUNDLE
79133
.getString("R_SetAuthenticationWhenIntegratedSecurityTrue");
80134
static final String ERR_MSG_NOT_AUTH_AND_USER_PASSWORD = TestUtils.R_BUNDLE
@@ -91,7 +145,8 @@ enum SqlAuthentication {
91145
SqlPassword,
92146
ActiveDirectoryPassword,
93147
ActiveDirectoryIntegrated,
94-
ActiveDirectoryServicePrincipal;
148+
ActiveDirectoryServicePrincipal,
149+
ActiveDirectoryServicePrincipalCertificate;
95150

96151
static SqlAuthentication valueOfString(String value) throws SQLServerException {
97152
SqlAuthentication method = null;
@@ -124,8 +179,9 @@ public static void getConfigs() throws Exception {
124179
azureUserName = getConfiguredProperty("azureUserName");
125180
azurePassword = getConfiguredProperty("azurePassword");
126181
azureGroupUserName = getConfiguredProperty("azureGroupUserName");
127-
azureAADPrincipalId = getConfiguredProperty("AADSecurePrincipalId");
128-
azureAADPrincipalSecret = getConfiguredProperty("AADSecurePrincipalSecret");
182+
183+
// password for service principal certificate
184+
certificatePassword = getConfiguredProperty("certificatePassword");
129185

130186
String prop = getConfiguredProperty("enableADIntegrated");
131187
enableADIntegrated = (null != prop && prop.equalsIgnoreCase("true")) ? true : false;
@@ -162,30 +218,34 @@ static void getFedauthInfo() {
162218
long interval = THROTTLE_RETRY_INTERVAL;
163219
while (retry <= THROTTLE_RETRY_COUNT) {
164220
try {
165-
if (null == fedauthPcaApp) {
166-
fedauthPcaApp = PublicClientApplication.builder(fedauthClientId)
167-
.executorService(Executors.newFixedThreadPool(1)).authority(stsurl).build();
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();
168228
}
169229

170-
final CompletableFuture<IAuthenticationResult> future = fedauthPcaApp
171-
.acquireToken(UserNamePasswordParameters.builder(Collections.singleton(spn + "/.default"),
172-
azureUserName, azurePassword.toCharArray()).build());
230+
final CompletableFuture<IAuthenticationResult> future = fedauthClientApp
231+
.acquireToken(ClientCredentialParameters.builder(scopes).build());
173232

174233
final IAuthenticationResult authenticationResult = future.get();
175234

176235
secondsBeforeExpiration = TimeUnit.MILLISECONDS
177236
.toSeconds(authenticationResult.expiresOnDate().getTime() - new Date().getTime());
178237
accessToken = authenticationResult.accessToken();
238+
179239
retry = THROTTLE_RETRY_COUNT + 1;
180240
} catch (MsalThrottlingException te) {
181241
interval = te.retryInMs();
182242
if (!checkForRetry(te, retry++, interval)) {
243+
te.printStackTrace();
183244
fail(ERR_FAILED_FEDAUTH + "no more retries: " + te.getMessage());
184245
}
185246
} catch (Exception e) {
186-
if (!checkForRetry(e, retry++, interval)) {
187-
fail(ERR_FAILED_FEDAUTH + "no more retries: " + e.getMessage());
188-
}
247+
e.printStackTrace();
248+
fail(ERR_FAILED_FEDAUTH + e.getMessage());
189249
}
190250
}
191251
}
@@ -195,8 +255,6 @@ static boolean checkForRetry(Exception e, int retry, long interval) {
195255
return false;
196256
}
197257
try {
198-
System.out
199-
.println(e.getMessage() + "Get FedAuth token failed, retry #" + retry + " in " + interval + " ms");
200258
Thread.sleep(interval);
201259
} catch (InterruptedException ex) {
202260
e.printStackTrace();
@@ -209,11 +267,12 @@ static boolean checkForRetry(Exception e, int retry, long interval) {
209267
void testUserName(Connection conn, String user, SqlAuthentication authentication) throws SQLException {
210268
try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
211269
rs.next();
212-
if (SqlAuthentication.ActiveDirectoryIntegrated != authentication) {
213-
assertTrue(user.equals(rs.getString(1)));
214-
} else {
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) {
215274
if (isWindows) {
216-
assertTrue(rs.getString(1).contains(System.getProperty("user.name")));
275+
assertTrue(rs.getString(1).contains(System.getProperty("user.name")), rs.getString(1));
217276
} else {
218277
// cannot verify user in kerberos tickets so just check it's not empty
219278
assertTrue(!rs.getString(1).isEmpty());

0 commit comments

Comments
 (0)