Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for ActiveDirectoryInteractive authentication #1464

Merged
merged 61 commits into from
Nov 28, 2020
Merged
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
c97b863
Fix AEv2 tests exclude for reqExternalSetup and cleanup (#1247)
lilgreenbird Feb 5, 2020
54b5a19
Fix | Add null check for getObject() with LocalTime and LocalDate (#1…
peterbae Feb 8, 2020
672b7d6
added all AKV tests to use reqExternalSetup tag so they will be skipp…
lilgreenbird Feb 10, 2020
3c3331b
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Mar 25, 2020
e2c5640
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Mar 26, 2020
aad6966
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Mar 28, 2020
92bf04c
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Mar 31, 2020
3ba5ab7
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Apr 4, 2020
d20823d
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Apr 7, 2020
4cc959f
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Apr 29, 2020
7b301f8
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Apr 30, 2020
56bcf13
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird May 7, 2020
744e0ca
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird May 12, 2020
df8fd41
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird May 19, 2020
652e68b
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird May 26, 2020
53736db
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird May 26, 2020
9ba6a42
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jun 2, 2020
6d156f7
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jun 5, 2020
e08ffe5
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jun 10, 2020
6b6cab2
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jun 18, 2020
c202590
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jun 24, 2020
0515d4b
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jun 24, 2020
2c63b58
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jun 25, 2020
78aa941
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jul 2, 2020
90e99cd
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jul 2, 2020
da1004b
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jul 6, 2020
9ca1284
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Jul 28, 2020
c67d8ed
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Aug 1, 2020
1d0a4ad
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Aug 5, 2020
f1b1dfb
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Aug 26, 2020
d9bad87
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Sep 2, 2020
a2e50b9
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Sep 9, 2020
7ff97de
enable ADintegrated tests for non-windows
lilgreenbird Sep 9, 2020
7cae3b4
fixed user test for kerberos
lilgreenbird Sep 11, 2020
c8c5a29
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Sep 16, 2020
d76368a
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Sep 22, 2020
e5aafd3
Merge branch 'dev' of https://github.com/lilgreenbird/mssql-jdbc into…
lilgreenbird Sep 22, 2020
7800824
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Oct 5, 2020
a8199bb
merged
lilgreenbird Oct 14, 2020
b6d475c
added ActiveDirectoryInteractive authentication
lilgreenbird Oct 29, 2020
6303db0
update
lilgreenbird Nov 11, 2020
f9f0e1f
cache
lilgreenbird Nov 13, 2020
add1141
cache
lilgreenbird Nov 14, 2020
d9e9b63
Merge remote-tracking branch 'upstream/dev' into mfa
lilgreenbird Nov 14, 2020
4c135f2
added clearUserTokenCache
lilgreenbird Nov 17, 2020
fbe56cc
cleanup
lilgreenbird Nov 18, 2020
5a4ea59
token cache aspect
lilgreenbird Nov 19, 2020
198720c
update
lilgreenbird Nov 19, 2020
cc44cd6
tests
lilgreenbird Nov 20, 2020
6f733b9
removed debug
lilgreenbird Nov 20, 2020
938c7af
username
lilgreenbird Nov 20, 2020
ba23801
error msg format
lilgreenbird Nov 20, 2020
062bd14
update error msg
lilgreenbird Nov 21, 2020
05935ce
update client id
lilgreenbird Nov 21, 2020
5533134
error msg fix
lilgreenbird Nov 21, 2020
53b5663
merged
lilgreenbird Nov 23, 2020
76407e2
added clearUserTokenCache
lilgreenbird Nov 23, 2020
7e5139a
review updates
lilgreenbird Nov 26, 2020
cedceaf
formatting
lilgreenbird Nov 26, 2020
bd428b2
removed debug lines
lilgreenbird Nov 26, 2020
7c166bf
merged
lilgreenbird Nov 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ final class TDS {
static final byte ADALWORKFLOW_ACTIVEDIRECTORYPASSWORD = 0x01;
static final byte ADALWORKFLOW_ACTIVEDIRECTORYINTEGRATED = 0x02;
static final byte ADALWORKFLOW_ACTIVEDIRECTORYMSI = 0x03;
static final byte ADALWORKFLOW_ACTIVEDIRECTORYSERVICEPRINCIPAL = 0x01; // Using the Password byte as that is the closest we have.
static final byte ADALWORKFLOW_ACTIVEDIRECTORYINTERACTIVE = 0x03;
static final byte ADALWORKFLOW_ACTIVEDIRECTORYSERVICEPRINCIPAL = 0x01; // Using the Password byte as that is the
// closest we have.
static final byte FEDAUTH_INFO_ID_STSURL = 0x01; // FedAuthInfoData is token endpoint URL from which to acquire fed
// auth token
static final byte FEDAUTH_INFO_ID_SPN = 0x02; // FedAuthInfoData is the SPN to use for acquiring fed auth token
Expand Down Expand Up @@ -2052,7 +2054,13 @@ else if (null != (trustStoreFileName = System.getProperty("javax.net.ssl.trustSt

final int read(byte[] data, int offset, int length) throws SQLServerException {
try {
// System.out.println("socket timeout:"+ tcpSocket.getSoTimeout());
lilgreenbird marked this conversation as resolved.
Show resolved Hide resolved
// tcpSocket.setSoTimeout(10000);

return inputStream.read(data, offset, length);
} catch (SocketException e) {
System.out.println("SocketTimeoutException:" + e.getMessage());
return 0; // Keep the compiler happy.
} catch (IOException e) {
if (logger.isLoggable(Level.FINE))
logger.fine(toString() + " read failed:" + e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made
* available under the terms of the MIT License. See the LICENSE file in the project root for more information.
*/

package com.microsoft.sqlserver.jdbc;

import com.microsoft.aad.msal4j.ITokenCacheAccessAspect;
import com.microsoft.aad.msal4j.ITokenCacheAccessContext;


/**
* Access aspect for accessing the token cache.
*
* MSAL token cache does not persist beyond lifetime of the application. This class implements the
* ITokenCacheAccessAspect interface to persist the token cache between application instances so subsequent
* authentications can use silent authentication if the user account is in the token cache.
*
* @see <a href="https://aka.ms/msal4j-token-cache">https://aka.ms/msal4j-token-cache</a>
*/
public class PersistentTokenCacheAccessAspect implements ITokenCacheAccessAspect {
private static PersistentTokenCacheAccessAspect instance = new PersistentTokenCacheAccessAspect();

private PersistentTokenCacheAccessAspect() {};

static PersistentTokenCacheAccessAspect getInstance() {
return instance;
}

/**
* Token cache in JSON format
*/
private String cache = null;

@Override
public synchronized void beforeCacheAccess(ITokenCacheAccessContext iTokenCacheAccessContext) {
if (null != cache && null != iTokenCacheAccessContext && null != iTokenCacheAccessContext.tokenCache()) {
iTokenCacheAccessContext.tokenCache().deserialize(cache);
}
}

@Override
public synchronized void afterCacheAccess(ITokenCacheAccessContext iTokenCacheAccessContext) {
if (null != iTokenCacheAccessContext && iTokenCacheAccessContext.hasCacheChanged()
&& null != iTokenCacheAccessContext.tokenCache())
cache = iTokenCacheAccessContext.tokenCache().serialize();
}

/**
* Clears User token cache. This will clear all account info so interactive login will be required on the next
* request to acquire an access token.
*/
static void clearUserTokenCache() {
if (null != instance.cache && !instance.cache.isEmpty()) {
instance.cache = null;
}
lilgreenbird marked this conversation as resolved.
Show resolved Hide resolved
}
}
lilgreenbird marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ class FederatedAuthenticationFeatureExtensionData implements Serializable {
case "ACTIVEDIRECTORYSERVICEPRINCIPAL":
this.authentication = SqlAuthentication.ActiveDirectoryServicePrincipal;
break;
case "ACTIVEDIRECTORYINTERACTIVE":
this.authentication = SqlAuthentication.ActiveDirectoryInteractive;
break;
default:
assert (false);
MessageFormat form = new MessageFormat(
Expand Down Expand Up @@ -949,6 +952,14 @@ static synchronized List<String> getColumnEncryptionTrustedMasterKeyPaths(String
}
}

/**
* Clears User token cache. This will clear all account info so interactive login will be required on the next
* request to acquire an access token.
*/
public static synchronized void clearUserTokenCache() {
PersistentTokenCacheAccessAspect.clearUserTokenCache();
}

Properties activeConnectionProperties; // the active set of connection properties
private boolean integratedSecurity = SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.getDefaultValue();
private boolean ntlmAuthentication = false;
Expand Down Expand Up @@ -3909,6 +3920,9 @@ int writeFedAuthFeatureRequest(boolean write, /* if false just calculates the le
case ActiveDirectoryMSI:
workflow = TDS.ADALWORKFLOW_ACTIVEDIRECTORYMSI;
break;
case ActiveDirectoryInteractive:
workflow = TDS.ADALWORKFLOW_ACTIVEDIRECTORYINTERACTIVE;
break;
case ActiveDirectoryServicePrincipal:
workflow = TDS.ADALWORKFLOW_ACTIVEDIRECTORYSERVICEPRINCIPAL;
break;
Expand Down Expand Up @@ -4016,7 +4030,9 @@ private void logon(LogonCommand command) throws SQLServerException {
|| ((authenticationString.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryIntegrated.toString())
|| authenticationString.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryMSI.toString())
|| authenticationString
.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryServicePrincipal.toString()))
.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryServicePrincipal.toString())
|| authenticationString
.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryInteractive.toString()))
&& fedAuthRequiredPreLoginResponse)) {
federatedAuthenticationInfoRequested = true;
fedAuthFeatureExtensionData = new FederatedAuthenticationFeatureExtensionData(TDS.TDS_FEDAUTH_LIBRARY_ADAL,
Expand Down Expand Up @@ -4455,6 +4471,8 @@ void onFedAuthInfo(SqlFedAuthInfo fedAuthInfo, TDSTokenHandler tdsTokenHandler)
&& null != activeConnectionProperties.getProperty(SQLServerDriverStringProperty.PASSWORD.toString()))
|| (authenticationString.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryIntegrated.toString())
|| authenticationString.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryMSI.toString())
|| authenticationString
.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryInteractive.toString())
&& fedAuthRequiredPreLoginResponse);

assert null != fedAuthInfo;
Expand Down Expand Up @@ -4507,7 +4525,6 @@ private SqlFedAuthToken getFedAuthToken(SqlFedAuthInfo fedAuthInfo) throws SQLSe
// Break out of the retry loop in successful case.
break;
} else if (authenticationString.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryIntegrated.toString())) {

// If operating system is windows and mssql-jdbc_auth is loaded then choose the DLL authentication.
if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("windows")
&& AuthenticationJNI.isDllLoaded()) {
Expand Down Expand Up @@ -4590,6 +4607,17 @@ private SqlFedAuthToken getFedAuthToken(SqlFedAuthInfo fedAuthInfo) throws SQLSe
}
// Break out of the retry loop in successful case.
break;
} else if (authenticationString.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryInteractive.toString())) {
if (!msalContextExists()) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_MSALMissing"));
throw new SQLServerException(form.format(new Object[] {authenticationString}), null, 0, null);
}
// interactive flow
fedAuthToken = SQLServerMSAL4JUtils.getSqlFedAuthTokenInteractive(fedAuthInfo, user,
authenticationString);

// Break out of the retry loop in successful case.
break;
}
}

Expand Down
11 changes: 8 additions & 3 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ enum SqlAuthentication {
ActiveDirectoryPassword,
ActiveDirectoryIntegrated,
ActiveDirectoryMSI,
ActiveDirectoryServicePrincipal;
ActiveDirectoryServicePrincipal,
ActiveDirectoryInteractive;

static SqlAuthentication valueOfString(String value) throws SQLServerException {
SqlAuthentication method = null;
Expand All @@ -86,6 +87,9 @@ static SqlAuthentication valueOfString(String value) throws SQLServerException {
} else if (value.toLowerCase(Locale.US)
.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryServicePrincipal.toString())) {
method = SqlAuthentication.ActiveDirectoryServicePrincipal;
} else if (value.toLowerCase(Locale.US)
.equalsIgnoreCase(SqlAuthentication.ActiveDirectoryInteractive.toString())) {
method = SqlAuthentication.ActiveDirectoryInteractive;
} else {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_InvalidConnectionSetting"));
Object[] msgArgs = {"authentication", value};
Expand Down Expand Up @@ -589,8 +593,9 @@ public final class SQLServerDriver implements java.sql.Driver {
SqlAuthentication.ActiveDirectoryPassword.toString(),
SqlAuthentication.ActiveDirectoryIntegrated.toString(),
SqlAuthentication.ActiveDirectoryMSI.toString(),
SqlAuthentication.ActiveDirectoryServicePrincipal
.toString()}),
SqlAuthentication.ActiveDirectoryServicePrincipal.toString(),
SqlAuthentication.ActiveDirectoryInteractive.toString()}),

new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.SOCKET_TIMEOUT.toString(),
Integer.toString(SQLServerDriverIntProperty.SOCKET_TIMEOUT.getDefaultValue()), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.FIPS.toString(),
Expand Down
102 changes: 90 additions & 12 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerMSAL4JUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.HashSet;
Expand All @@ -16,37 +18,43 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;

import javax.security.auth.kerberos.KerberosPrincipal;

import com.microsoft.aad.msal4j.IAccount;
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.IClientCredential;
import com.microsoft.aad.msal4j.IntegratedWindowsAuthenticationParameters;
import com.microsoft.aad.msal4j.InteractiveRequestParameters;
import com.microsoft.aad.msal4j.MsalInteractionRequiredException;
import com.microsoft.aad.msal4j.PublicClientApplication;
import com.microsoft.aad.msal4j.SilentParameters;
import com.microsoft.aad.msal4j.SystemBrowserOptions;
import com.microsoft.aad.msal4j.UserNamePasswordParameters;
import com.microsoft.sqlserver.jdbc.SQLServerConnection.ActiveDirectoryAuthentication;

import com.microsoft.sqlserver.jdbc.SQLServerConnection.SqlFedAuthInfo;


class SQLServerMSAL4JUtils {

static final String REDIRECTURI = "http://localhost";

static final private java.util.logging.Logger logger = java.util.logging.Logger
.getLogger("com.microsoft.sqlserver.jdbc.SQLServerMSAL4JUtils");

static SqlFedAuthToken getSqlFedAuthToken(SqlFedAuthInfo fedAuthInfo, String user, String password,
String authenticationString) throws SQLServerException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
ExecutorService executorService = Executors.newSingleThreadExecutor();

try {
final PublicClientApplication clientApplication = PublicClientApplication
final PublicClientApplication pca = PublicClientApplication
.builder(ActiveDirectoryAuthentication.JDBC_FEDAUTH_CLIENT_ID).executorService(executorService)
.authority(fedAuthInfo.stsurl).build();
final CompletableFuture<IAuthenticationResult> future = clientApplication
.acquireToken(UserNamePasswordParameters
.builder(Collections.singleton(fedAuthInfo.spn + "/.default"), user, password.toCharArray())
.build());
final CompletableFuture<IAuthenticationResult> future = pca.acquireToken(UserNamePasswordParameters
.builder(Collections.singleton(fedAuthInfo.spn + "/.default"), user, password.toCharArray())
.build());

final IAuthenticationResult authenticationResult = future.get();
return new SqlFedAuthToken(authenticationResult.accessToken(), authenticationResult.expiresOnDate());
Expand All @@ -61,7 +69,7 @@ static SqlFedAuthToken getSqlFedAuthToken(SqlFedAuthInfo fedAuthInfo, String use

static SqlFedAuthToken getSqlFedAuthTokenPrincipal(SqlFedAuthInfo fedAuthInfo, String aadPrincipalID,
String aadPrincipalSecret, String authenticationString) throws SQLServerException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
ExecutorService executorService = Executors.newSingleThreadExecutor();
try {
String defaultScopeSuffix = "/.default";
String scope = fedAuthInfo.spn.endsWith(defaultScopeSuffix) ? fedAuthInfo.spn
Expand All @@ -87,7 +95,7 @@ static SqlFedAuthToken getSqlFedAuthTokenPrincipal(SqlFedAuthInfo fedAuthInfo, S

static SqlFedAuthToken getSqlFedAuthTokenIntegrated(SqlFedAuthInfo fedAuthInfo,
String authenticationString) throws SQLServerException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
ExecutorService executorService = Executors.newSingleThreadExecutor();

try {
/*
Expand All @@ -101,10 +109,10 @@ static SqlFedAuthToken getSqlFedAuthTokenIntegrated(SqlFedAuthInfo fedAuthInfo,
logger.fine(logger.toString() + " realm name is:" + kerberosPrincipal.getRealm());
}

final PublicClientApplication clientApplication = PublicClientApplication
final PublicClientApplication pca = PublicClientApplication
.builder(ActiveDirectoryAuthentication.JDBC_FEDAUTH_CLIENT_ID).executorService(executorService)
.authority(fedAuthInfo.stsurl).build();
final CompletableFuture<IAuthenticationResult> future = clientApplication
final CompletableFuture<IAuthenticationResult> future = pca
.acquireToken(IntegratedWindowsAuthenticationParameters
.builder(Collections.singleton(fedAuthInfo.spn + "/.default"), user).build());

Expand All @@ -119,6 +127,76 @@ static SqlFedAuthToken getSqlFedAuthTokenIntegrated(SqlFedAuthInfo fedAuthInfo,
}
}

static SqlFedAuthToken getSqlFedAuthTokenInteractive(SqlFedAuthInfo fedAuthInfo, String user,
String authenticationString) throws SQLServerException {
ExecutorService executorService = Executors.newSingleThreadExecutor();

try {
PublicClientApplication pca = PublicClientApplication
.builder(ActiveDirectoryAuthentication.JDBC_FEDAUTH_CLIENT_ID).executorService(executorService)
.setTokenCacheAccessAspect(PersistentTokenCacheAccessAspect.getInstance())
.authority(fedAuthInfo.stsurl).logPii((logger.isLoggable(Level.FINE)) ? true : false).build();

CompletableFuture<IAuthenticationResult> future = null;
IAuthenticationResult authenticationResult = null;

// try to acquire token silently if user account found in cache
try {
Set<IAccount> accountsInCache = pca.getAccounts().join();
if (null != accountsInCache && !accountsInCache.isEmpty() && null != user && !user.isEmpty()) {
IAccount account = getAccountByUsername(accountsInCache, user);
if (null != account) {
if (logger.isLoggable(Level.FINE)) {
logger.fine(logger.toString() + "Silent authentication for user:" + user);
}
SilentParameters silentParameters = SilentParameters
.builder(Collections.singleton(fedAuthInfo.spn + "/.default"), account).build();

future = pca.acquireTokenSilently(silentParameters);
}
}
} catch (MsalInteractionRequiredException e) {
// not an error, need to get token interactively
}

if (null != future) {
authenticationResult = future.get();
} else {
// acquire token interactively with system browser
if (logger.isLoggable(Level.FINE)) {
logger.fine(logger.toString() + "Interactive authentication");
}
InteractiveRequestParameters parameters = InteractiveRequestParameters.builder(new URI(REDIRECTURI))
.systemBrowserOptions(SystemBrowserOptions.builder()
.htmlMessageSuccess(SQLServerResource.getResource("R_MSALAuthComplete")).build())
.loginHint(user).scopes(Collections.singleton(fedAuthInfo.spn + "/.default")).build();

future = pca.acquireToken(parameters);
authenticationResult = future.get();
}

return new SqlFedAuthToken(authenticationResult.accessToken(), authenticationResult.expiresOnDate());
} catch (MalformedURLException | InterruptedException | URISyntaxException e) {
throw new SQLServerException(e.getMessage(), e);
} catch (ExecutionException e) {
throw getCorrectedException(e, user, authenticationString);
} finally {
executorService.shutdown();
}
}

// Helper function to return account containing user name from set of accounts, or null if no match
private static IAccount getAccountByUsername(Set<IAccount> accounts, String username) {
if (!accounts.isEmpty()) {
for (IAccount account : accounts) {
if (account.username().equals(username)) {
return account;
}
}
}
return null;
}
lilgreenbird marked this conversation as resolved.
Show resolved Hide resolved

private static SQLServerException getCorrectedException(ExecutionException e, String user,
String authenticationString) {
if (logger.isLoggable(Level.SEVERE)) {
Expand Down
Loading