mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-04 01:25:43 -05:00
Introduce AAD interactive auth mode (#1860)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#nullable disable
|
||||
|
||||
using Microsoft.SqlTools.Hosting.Contracts;
|
||||
using static Microsoft.SqlTools.Shared.Utility.Constants;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
{
|
||||
@@ -52,7 +53,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
CategoryValues = new CategoryValue[]
|
||||
{ new CategoryValue { DisplayName = "SQL Login", Name = "SqlLogin" },
|
||||
new CategoryValue { DisplayName = "Windows Authentication", Name = "Integrated" },
|
||||
new CategoryValue { DisplayName = "Azure Active Directory - Universal with MFA support", Name = "AzureMFA" }
|
||||
new CategoryValue { DisplayName = "Azure Active Directory - Universal with MFA support", Name = AzureMFA }
|
||||
},
|
||||
IsIdentity = true,
|
||||
IsRequired = true,
|
||||
|
||||
@@ -23,7 +23,9 @@ using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
using static Microsoft.SqlTools.Shared.Utility.Constants;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.SqlTools.Authentication.Sql;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
{
|
||||
@@ -143,17 +145,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
{
|
||||
RequestSecurityTokenParams message = new RequestSecurityTokenParams()
|
||||
{
|
||||
Authority = authority,
|
||||
Provider = "Azure",
|
||||
Authority = authority,
|
||||
Resource = resource,
|
||||
Scope = scope
|
||||
Scopes = new string[] { scope }
|
||||
};
|
||||
|
||||
RequestSecurityTokenResponse response = await Instance.ServiceHost.SendRequest(SecurityTokenRequest.Type, message, true);
|
||||
RequestSecurityTokenResponse response = await Instance.ServiceHost.SendRequest(SecurityTokenRequest.Type, message, true).ConfigureAwait(false);
|
||||
|
||||
return response.Token;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables configured 'Sql Authentication Provider' for 'Active Directory Interactive' authentication mode to be used
|
||||
/// when user chooses 'Azure MFA'.
|
||||
/// </summary>
|
||||
public bool EnableSqlAuthenticationProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a connection queue for given type
|
||||
/// </summary>
|
||||
@@ -248,7 +256,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
if (this.TryFindConnection(ownerUri, out connInfo))
|
||||
{
|
||||
// If not an azure connection, no need to refresh token
|
||||
if (connInfo.ConnectionDetails.AuthenticationType != "AzureMFA")
|
||||
if (connInfo.ConnectionDetails.AuthenticationType != AzureMFA)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -594,7 +602,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
connectionInfo.IsSqlDb = serverInfo.EngineEditionId == (int)DatabaseEngineEdition.SqlDatabase;
|
||||
connectionInfo.IsSqlDW = (serverInfo.EngineEditionId == (int)DatabaseEngineEdition.SqlDataWarehouse);
|
||||
// Determines that access token is used for creating connection.
|
||||
connectionInfo.IsAzureAuth = connectionInfo.ConnectionDetails.AuthenticationType == "AzureMFA";
|
||||
connectionInfo.IsAzureAuth = connectionInfo.ConnectionDetails.AuthenticationType == AzureMFA;
|
||||
connectionInfo.EngineEdition = (DatabaseEngineEdition)serverInfo.EngineEditionId;
|
||||
// Azure Data Studio supports SQL Server 2014 and later releases.
|
||||
response.IsSupportedVersion = serverInfo.IsCloud || serverInfo.ServerMajorVersion >= 12;
|
||||
@@ -1061,10 +1069,20 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
return handler.HandleRequest(this.connectionFactory, info);
|
||||
}
|
||||
|
||||
public void InitializeService(IProtocolEndpoint serviceHost)
|
||||
public void InitializeService(IProtocolEndpoint serviceHost, ServiceLayerCommandOptions commandOptions)
|
||||
{
|
||||
this.ServiceHost = serviceHost;
|
||||
|
||||
if (commandOptions != null && commandOptions.EnableSqlAuthenticationProvider)
|
||||
{
|
||||
// Register SqlAuthenticationProvider with SqlConnection for AAD Interactive (MFA) authentication.
|
||||
var provider = new AuthenticationProvider(commandOptions.ApplicationName);
|
||||
SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive, provider);
|
||||
|
||||
this.EnableSqlAuthenticationProvider = true;
|
||||
Logger.Information("Registering implementation of SQL Authentication provider for 'Active Directory Interactive' authentication mode.");
|
||||
}
|
||||
|
||||
// Register request and event handlers with the Service Host
|
||||
serviceHost.SetRequestHandler(ConnectionRequest.Type, HandleConnectRequest, true);
|
||||
serviceHost.SetRequestHandler(CancelConnectRequest.Type, HandleCancelConnectRequest, true);
|
||||
@@ -1304,31 +1322,46 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
|
||||
connectionBuilder = new SqlConnectionStringBuilder
|
||||
{
|
||||
["Data Source"] = dataSource,
|
||||
["User Id"] = connectionDetails.UserName,
|
||||
["Password"] = connectionDetails.Password
|
||||
DataSource = dataSource
|
||||
};
|
||||
}
|
||||
|
||||
// Check for any optional parameters
|
||||
if (!string.IsNullOrEmpty(connectionDetails.DatabaseName))
|
||||
{
|
||||
connectionBuilder["Initial Catalog"] = connectionDetails.DatabaseName;
|
||||
connectionBuilder.InitialCatalog = connectionDetails.DatabaseName;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(connectionDetails.AuthenticationType))
|
||||
{
|
||||
switch (connectionDetails.AuthenticationType)
|
||||
{
|
||||
case "Integrated":
|
||||
case Integrated:
|
||||
connectionBuilder.IntegratedSecurity = true;
|
||||
break;
|
||||
case "SqlLogin":
|
||||
case SqlLogin:
|
||||
connectionBuilder.UserID = connectionDetails.UserName;
|
||||
connectionBuilder.Password = connectionDetails.Password;
|
||||
connectionBuilder.Authentication = SqlAuthenticationMethod.SqlPassword;
|
||||
break;
|
||||
case "AzureMFA":
|
||||
connectionBuilder.UserID = "";
|
||||
connectionBuilder.Password = "";
|
||||
case AzureMFA:
|
||||
if (Instance.EnableSqlAuthenticationProvider)
|
||||
{
|
||||
connectionBuilder.UserID = connectionDetails.UserName;
|
||||
connectionDetails.AuthenticationType = ActiveDirectoryInteractive;
|
||||
connectionBuilder.Authentication = SqlAuthenticationMethod.ActiveDirectoryInteractive;
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionBuilder.UserID = "";
|
||||
}
|
||||
break;
|
||||
case "ActiveDirectoryPassword":
|
||||
case ActiveDirectoryInteractive:
|
||||
connectionBuilder.UserID = connectionDetails.UserName;
|
||||
connectionBuilder.Authentication = SqlAuthenticationMethod.ActiveDirectoryInteractive;
|
||||
break;
|
||||
case ActiveDirectoryPassword:
|
||||
connectionBuilder.UserID = connectionDetails.UserName;
|
||||
connectionBuilder.Password = connectionDetails.Password;
|
||||
connectionBuilder.Authentication = SqlAuthenticationMethod.ActiveDirectoryPassword;
|
||||
break;
|
||||
default:
|
||||
@@ -1337,16 +1370,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
}
|
||||
if (!string.IsNullOrEmpty(connectionDetails.ColumnEncryptionSetting))
|
||||
{
|
||||
switch (connectionDetails.ColumnEncryptionSetting.ToUpper())
|
||||
if (Enum.TryParse<SqlConnectionColumnEncryptionSetting>(connectionDetails.ColumnEncryptionSetting, true, out var value))
|
||||
{
|
||||
case "ENABLED":
|
||||
connectionBuilder.ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Enabled;
|
||||
break;
|
||||
case "DISABLED":
|
||||
connectionBuilder.ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidColumnEncryptionSetting(connectionDetails.ColumnEncryptionSetting));
|
||||
connectionBuilder.ColumnEncryptionSetting = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidColumnEncryptionSetting(connectionDetails.ColumnEncryptionSetting));
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(connectionDetails.SecureEnclaves))
|
||||
@@ -1365,36 +1395,30 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
}
|
||||
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationProtocol))
|
||||
{
|
||||
if (string.IsNullOrEmpty(connectionDetails.ColumnEncryptionSetting) || connectionDetails.ColumnEncryptionSetting.ToUpper() == "DISABLED"
|
||||
if (connectionBuilder.ColumnEncryptionSetting != SqlConnectionColumnEncryptionSetting.Enabled
|
||||
|| string.IsNullOrEmpty(connectionDetails.SecureEnclaves) || connectionDetails.SecureEnclaves.ToUpper() == "DISABLED")
|
||||
{
|
||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination);
|
||||
}
|
||||
|
||||
switch (connectionDetails.EnclaveAttestationProtocol.ToUpper())
|
||||
if (Enum.TryParse<SqlConnectionAttestationProtocol>(connectionDetails.EnclaveAttestationProtocol, true, out var value))
|
||||
{
|
||||
case "AAS":
|
||||
connectionBuilder.AttestationProtocol = SqlConnectionAttestationProtocol.AAS;
|
||||
break;
|
||||
case "HGS":
|
||||
connectionBuilder.AttestationProtocol = SqlConnectionAttestationProtocol.HGS;
|
||||
break;
|
||||
case "NONE":
|
||||
connectionBuilder.AttestationProtocol = SqlConnectionAttestationProtocol.None;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidEnclaveAttestationProtocol(connectionDetails.EnclaveAttestationProtocol));
|
||||
connectionBuilder.AttestationProtocol = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidEnclaveAttestationProtocol(connectionDetails.EnclaveAttestationProtocol));
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationUrl))
|
||||
{
|
||||
if (string.IsNullOrEmpty(connectionDetails.ColumnEncryptionSetting) || connectionDetails.ColumnEncryptionSetting.ToUpper() == "DISABLED"
|
||||
if (connectionBuilder.ColumnEncryptionSetting != SqlConnectionColumnEncryptionSetting.Enabled
|
||||
|| string.IsNullOrEmpty(connectionDetails.SecureEnclaves) || connectionDetails.SecureEnclaves.ToUpper() == "DISABLED")
|
||||
{
|
||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination);
|
||||
}
|
||||
|
||||
if(connectionBuilder.AttestationProtocol == SqlConnectionAttestationProtocol.None)
|
||||
if (connectionBuilder.AttestationProtocol == SqlConnectionAttestationProtocol.None)
|
||||
{
|
||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAttestationProtocolNoneWithUrl);
|
||||
}
|
||||
@@ -1456,19 +1480,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
}
|
||||
if (!string.IsNullOrEmpty(connectionDetails.ApplicationIntent))
|
||||
{
|
||||
ApplicationIntent intent;
|
||||
switch (connectionDetails.ApplicationIntent)
|
||||
if (Enum.TryParse<ApplicationIntent>(connectionDetails.ApplicationIntent, true, out ApplicationIntent value))
|
||||
{
|
||||
case "ReadOnly":
|
||||
intent = ApplicationIntent.ReadOnly;
|
||||
break;
|
||||
case "ReadWrite":
|
||||
intent = ApplicationIntent.ReadWrite;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidIntent(connectionDetails.ApplicationIntent));
|
||||
connectionBuilder.ApplicationIntent = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidIntent(connectionDetails.ApplicationIntent));
|
||||
}
|
||||
connectionBuilder.ApplicationIntent = intent;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(connectionDetails.CurrentLanguage))
|
||||
{
|
||||
@@ -1585,7 +1604,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
ApplicationIntent = builder.ApplicationIntent.ToString(),
|
||||
ApplicationName = builder.ApplicationName,
|
||||
AttachDbFilename = builder.AttachDBFilename,
|
||||
AuthenticationType = builder.IntegratedSecurity ? "Integrated" : "SqlLogin",
|
||||
AuthenticationType = builder.IntegratedSecurity ? "Integrated" :
|
||||
(builder.Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive
|
||||
? "ActiveDirectoryInteractive" : "SqlLogin"),
|
||||
ConnectRetryCount = builder.ConnectRetryCount,
|
||||
ConnectRetryInterval = builder.ConnectRetryInterval,
|
||||
ConnectTimeout = builder.ConnectTimeout,
|
||||
@@ -1793,7 +1814,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
SqlConnection sqlConn = new SqlConnection(connectionString);
|
||||
|
||||
// Fill in Azure authentication token if needed
|
||||
if (connInfo.ConnectionDetails.AzureAccountToken != null)
|
||||
if (connInfo.ConnectionDetails.AzureAccountToken != null && connInfo.ConnectionDetails.AuthenticationType == AzureMFA)
|
||||
{
|
||||
sqlConn.AccessToken = connInfo.ConnectionDetails.AzureAccountToken;
|
||||
}
|
||||
@@ -1824,7 +1845,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
{
|
||||
var sqlConnection = ConnectionService.OpenSqlConnection(connInfo, featureName);
|
||||
ServerConnection serverConnection;
|
||||
if (connInfo.ConnectionDetails.AzureAccountToken != null)
|
||||
if (connInfo.ConnectionDetails.AzureAccountToken != null && connInfo.ConnectionDetails.AuthenticationType == AzureMFA)
|
||||
{
|
||||
serverConnection = new ServerConnection(sqlConnection, new AzureAccessToken(connInfo.ConnectionDetails.AzureAccountToken));
|
||||
}
|
||||
|
||||
@@ -11,25 +11,25 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
class RequestSecurityTokenParams
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the address of the authority to issue token.
|
||||
/// </summary>
|
||||
public string Authority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the provider that indicates the type of linked account to query.
|
||||
/// </summary>
|
||||
public string Provider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the authority URL from where token is requested.
|
||||
/// </summary>
|
||||
public string Authority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier of the target resource that is the recipient of the requested token.
|
||||
/// </summary>
|
||||
public string Resource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scope of the authentication request.
|
||||
/// Gets or sets the scope array of the authentication request.
|
||||
/// </summary>
|
||||
public string Scope { get; set; }
|
||||
public string [] Scopes { get; set; }
|
||||
}
|
||||
|
||||
class RequestSecurityTokenResponse
|
||||
|
||||
@@ -8,6 +8,7 @@ using Microsoft.SqlServer.Dac;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.TaskServices;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using static Microsoft.SqlTools.Shared.Utility.Constants;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
@@ -86,7 +87,9 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
|
||||
try
|
||||
{
|
||||
// Pass in Azure authentication token if needed
|
||||
this.DacServices = this.ConnInfo.ConnectionDetails.AzureAccountToken != null ? new DacServices(this.ConnectionString, new AccessTokenProvider(this.ConnInfo.ConnectionDetails.AzureAccountToken)) : new DacServices(this.ConnectionString);
|
||||
this.DacServices = this.ConnInfo.ConnectionDetails.AzureAccountToken != null && this.ConnInfo.ConnectionDetails.AuthenticationType == AzureMFA
|
||||
? new DacServices(this.ConnectionString, new AccessTokenProvider(this.ConnInfo.ConnectionDetails.AzureAccountToken))
|
||||
: new DacServices(this.ConnectionString);
|
||||
Execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -40,6 +40,7 @@ using Microsoft.SqlTools.ServiceLayer.SqlAssessment;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlProjects;
|
||||
using Microsoft.SqlTools.ServiceLayer.TableDesigner;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Workspace;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer
|
||||
@@ -53,7 +54,7 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
private static object lockObject = new object();
|
||||
private static bool isLoaded;
|
||||
|
||||
internal static ServiceHost CreateAndStartServiceHost(SqlToolsContext sqlToolsContext, Stream? inputStream = null, Stream? outputStream = null)
|
||||
internal static ServiceHost CreateAndStartServiceHost(SqlToolsContext sqlToolsContext, ServiceLayerCommandOptions? commandOptions, Stream? inputStream = null, Stream? outputStream = null)
|
||||
{
|
||||
ServiceHost serviceHost = ServiceHost.Instance;
|
||||
lock (lockObject)
|
||||
@@ -63,7 +64,7 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
// Grab the instance of the service host
|
||||
serviceHost.Initialize(inputStream, outputStream);
|
||||
|
||||
InitializeRequestHandlersAndServices(serviceHost, sqlToolsContext);
|
||||
InitializeRequestHandlersAndServices(serviceHost, sqlToolsContext, commandOptions);
|
||||
|
||||
// Start the service only after all request handlers are setup. This is vital
|
||||
// as otherwise the Initialize event can be lost - it's processed and discarded before the handler
|
||||
@@ -75,7 +76,7 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
return serviceHost;
|
||||
}
|
||||
|
||||
private static void InitializeRequestHandlersAndServices(ServiceHost serviceHost, SqlToolsContext sqlToolsContext)
|
||||
private static void InitializeRequestHandlersAndServices(ServiceHost serviceHost, SqlToolsContext sqlToolsContext, ServiceLayerCommandOptions? commandOptions)
|
||||
{
|
||||
// Load extension provider, which currently finds all exports in current DLL. Can be changed to find based
|
||||
// on directory or assembly list quite easily in the future
|
||||
@@ -96,7 +97,7 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
LanguageService.Instance.InitializeService(serviceHost, sqlToolsContext);
|
||||
serviceProvider.RegisterSingleService(LanguageService.Instance);
|
||||
|
||||
ConnectionService.Instance.InitializeService(serviceHost);
|
||||
ConnectionService.Instance.InitializeService(serviceHost, commandOptions);
|
||||
serviceProvider.RegisterSingleService(ConnectionService.Instance);
|
||||
|
||||
CredentialService.Instance.InitializeService(serviceHost);
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
<ProjectReference Include="../Microsoft.SqlTools.Hosting/Microsoft.SqlTools.Hosting.csproj" />
|
||||
<ProjectReference Include="../Microsoft.SqlTools.Credentials/Microsoft.SqlTools.Credentials.csproj" />
|
||||
<ProjectReference Include="../Microsoft.SqlTools.ManagedBatchParser/Microsoft.SqlTools.ManagedBatchParser.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.SqlTools.Authentication\Microsoft.SqlTools.Authentication.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.SqlTools.Shared\Microsoft.SqlTools.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\Notice.txt">
|
||||
|
||||
@@ -400,7 +400,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
|
||||
var builder = ConnectionService.CreateConnectionStringBuilder(session.ConnectionInfo.ConnectionDetails);
|
||||
builder.InitialCatalog = node.NodeValue;
|
||||
builder.ApplicationName = TableDesignerService.TableDesignerApplicationName;
|
||||
var azureToken = session.ConnectionInfo.ConnectionDetails.AzureAccountToken;
|
||||
// Set Access Token only when authentication mode is not specified.
|
||||
var azureToken = builder.Authentication == SqlAuthenticationMethod.NotSpecified
|
||||
? session.ConnectionInfo.ConnectionDetails.AzureAccountToken : null;
|
||||
TableDesignerCacheManager.StartDatabaseModelInitialization(builder.ToString(), azureToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -41,7 +41,16 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
logFilePath = Logger.GenerateLogFilePath("sqltools");
|
||||
}
|
||||
|
||||
Logger.Initialize(tracingLevel: commandOptions.TracingLevel, logFilePath: logFilePath, traceSource: "sqltools", commandOptions.AutoFlushLog);
|
||||
Logger.Initialize(tracingLevel: commandOptions.TracingLevel, commandOptions.PiiLogging, logFilePath: logFilePath, traceSource: "sqltools", commandOptions.AutoFlushLog);
|
||||
|
||||
// Register PII Logging configuration change callback
|
||||
Workspace.WorkspaceService<SqlToolsSettings>.Instance.RegisterConfigChangeCallback((newSettings, oldSettings, context) =>
|
||||
{
|
||||
Logger.IsPiiEnabled = newSettings?.MssqlTools?.PiiLogging ?? false;
|
||||
Logger.Information(Logger.IsPiiEnabled ? "PII Logging enabled" : "PII Logging disabled");
|
||||
return Task.FromResult(true);
|
||||
});
|
||||
|
||||
// Only enable SQL Client logging when verbose or higher to avoid extra overhead when the
|
||||
// detailed logging it provides isn't needed
|
||||
if (Logger.TracingLevel.HasFlag(SourceLevels.Verbose))
|
||||
@@ -53,7 +62,7 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
var hostDetails = new HostDetails(version: new Version(1, 0));
|
||||
|
||||
SqlToolsContext sqlToolsContext = new SqlToolsContext(hostDetails);
|
||||
ServiceHost serviceHost = HostLoader.CreateAndStartServiceHost(sqlToolsContext);
|
||||
ServiceHost serviceHost = HostLoader.CreateAndStartServiceHost(sqlToolsContext, commandOptions);
|
||||
serviceHost.MessageDispatcher.ParallelMessageProcessing = commandOptions.ParallelMessageProcessing;
|
||||
|
||||
// If this service was started by another process, then it should shutdown when that parent process does.
|
||||
|
||||
@@ -17,6 +17,7 @@ using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using static Microsoft.SqlTools.Shared.Utility.Constants;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
||||
@@ -187,7 +188,9 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
||||
case SchemaCompareEndpointType.Database:
|
||||
{
|
||||
string connectionString = GetConnectionString(connInfo, endpointInfo.DatabaseName);
|
||||
return connInfo.ConnectionDetails?.AzureAccountToken != null
|
||||
|
||||
// Set Access Token only when authentication mode is not specified.
|
||||
return connInfo.ConnectionDetails?.AzureAccountToken != null && connInfo.ConnectionDetails.AuthenticationType == AzureMFA
|
||||
? new SchemaCompareDatabaseEndpoint(connectionString, new AccessTokenProvider(connInfo.ConnectionDetails.AzureAccountToken))
|
||||
: new SchemaCompareDatabaseEndpoint(connectionString);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||
using Microsoft.SqlTools.ServiceLayer.Scripting.Contracts;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using static Microsoft.SqlTools.Shared.Utility.Constants;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
||||
@@ -109,7 +110,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
||||
if (connInfo != null)
|
||||
{
|
||||
parameters.ConnectionString = ConnectionService.BuildConnectionString(connInfo.ConnectionDetails);
|
||||
accessToken = connInfo.ConnectionDetails.AzureAccountToken;
|
||||
// Set Access Token only when authentication type is AzureMFA.
|
||||
if (connInfo.ConnectionDetails.AuthenticationType == AzureMFA)
|
||||
{
|
||||
accessToken = connInfo.ConnectionDetails.AzureAccountToken;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
/// group such as Intellisense is defined on a serialized setting it's used in the order of mssql, then sql, then
|
||||
/// falls back to a default value.
|
||||
/// </summary>
|
||||
public class CompoundToolsSettingsValues: ISqlToolsSettingsValues
|
||||
public class CompoundToolsSettingsValues : ISqlToolsSettingsValues
|
||||
{
|
||||
private List<ISqlToolsSettingsValues> priorityList = new List<ISqlToolsSettingsValues>();
|
||||
private SqlToolsSettingsValues defaultValues;
|
||||
@@ -44,11 +44,11 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
/// Gets or sets the detailed IntelliSense settings
|
||||
/// </summary>
|
||||
public IntelliSenseSettings IntelliSense
|
||||
{
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingOrDefault((settings) => settings.IntelliSense);
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
priorityList[0].IntelliSense = value;
|
||||
@@ -59,11 +59,11 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
/// Gets or sets the query execution settings
|
||||
/// </summary>
|
||||
public QueryExecutionSettings QueryExecutionSettings
|
||||
{
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingOrDefault((settings) => settings.QueryExecutionSettings);
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
priorityList[0].QueryExecutionSettings = value;
|
||||
@@ -74,11 +74,11 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
/// Gets or sets the formatter settings
|
||||
/// </summary>
|
||||
public FormatterSettings Format
|
||||
{
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingOrDefault((settings) => settings.Format);
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
priorityList[0].Format = value;
|
||||
@@ -89,15 +89,24 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
/// Gets or sets the object explorer settings
|
||||
/// </summary>
|
||||
public ObjectExplorerSettings ObjectExplorer
|
||||
{
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetSettingOrDefault((settings) => settings.ObjectExplorer);
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
priorityList[0].ObjectExplorer = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets PII Logging setting.
|
||||
/// </summary>
|
||||
public bool PiiLogging
|
||||
{
|
||||
get => GetSettingOrDefault((settings) => settings.PiiLogging);
|
||||
set => priorityList[0].PiiLogging = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
{
|
||||
/// <summary>
|
||||
@@ -31,5 +33,10 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
/// Object Explorer specific settings
|
||||
/// </summary>
|
||||
ObjectExplorerSettings ObjectExplorer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PII Logging setting
|
||||
/// </summary>
|
||||
Boolean PiiLogging { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
@@ -25,6 +26,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
QueryExecutionSettings = new QueryExecutionSettings();
|
||||
Format = new FormatterSettings();
|
||||
TableDesigner = new TableDesignerSettings();
|
||||
PiiLogging = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,5 +59,11 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
|
||||
/// </summary>
|
||||
[JsonProperty("tableDesigner")]
|
||||
public TableDesignerSettings TableDesigner { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the setting to enable PII Logging.
|
||||
/// </summary>
|
||||
[JsonProperty("piiLogging")]
|
||||
public Boolean PiiLogging { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1800,7 +1800,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
|
||||
connectionStringBuilder.InitialCatalog = tableInfo.Database;
|
||||
connectionStringBuilder.ApplicationName = TableDesignerService.TableDesignerApplicationName;
|
||||
var connectionString = connectionStringBuilder.ToString();
|
||||
tableDesigner = new Dac.TableDesigner(connectionString, tableInfo.AccessToken, tableInfo.Schema, tableInfo.Name, tableInfo.IsNewTable);
|
||||
|
||||
// Set Access Token only when authentication mode is not specified.
|
||||
var accessToken = connectionStringBuilder.Authentication == SqlAuthenticationMethod.NotSpecified
|
||||
? tableInfo.AccessToken : null;
|
||||
tableDesigner = new Dac.TableDesigner(connectionString, accessToken, tableInfo.Schema, tableInfo.Name, tableInfo.IsNewTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Utility
|
||||
{
|
||||
class ServiceLayerCommandOptions : CommandOptions
|
||||
public class ServiceLayerCommandOptions : CommandOptions
|
||||
{
|
||||
internal const string ServiceLayerServiceName = "MicrosoftSqlToolsServiceLayer.exe";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user