mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 18:47:57 -05:00
Support passing Http proxy URL and Strict SSL flag to Authenticator (#2256)
This commit is contained in:
@@ -162,6 +162,7 @@ namespace Microsoft.SqlTools.Authentication
|
|||||||
private IPublicClientApplication CreatePublicClientAppInstance(string authority, string audience) =>
|
private IPublicClientApplication CreatePublicClientAppInstance(string authority, string audience) =>
|
||||||
PublicClientApplicationBuilder.Create(this.configuration.AppClientId)
|
PublicClientApplicationBuilder.Create(this.configuration.AppClientId)
|
||||||
.WithAuthority(authority, audience)
|
.WithAuthority(authority, audience)
|
||||||
|
.WithHttpClientFactory(new HttpClientProxyFactory(this.configuration.HttpProxyUrl, this.configuration.HttpProxyStrictSSL))
|
||||||
.WithClientName(this.configuration.AppName)
|
.WithClientName(this.configuration.AppName)
|
||||||
.WithLogging(Utils.MSALLogCallback)
|
.WithLogging(Utils.MSALLogCallback)
|
||||||
.WithDefaultRedirectUri()
|
.WithDefaultRedirectUri()
|
||||||
|
|||||||
@@ -31,11 +31,23 @@ namespace Microsoft.SqlTools.Authentication.Utility
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string CacheFileName { get; set; }
|
public string CacheFileName { get; set; }
|
||||||
|
|
||||||
public AuthenticatorConfiguration(string appClientId, string appName, string cacheFolderPath, string cacheFileName) {
|
/// <summary>
|
||||||
|
/// Proxy URL defined by end user.
|
||||||
|
/// </summary>
|
||||||
|
public string? HttpProxyUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the proxy server certificate must be verified against list of configured CAs.
|
||||||
|
/// </summary>
|
||||||
|
public bool HttpProxyStrictSSL { get; set; }
|
||||||
|
|
||||||
|
public AuthenticatorConfiguration(string appClientId, string appName, string cacheFolderPath, string cacheFileName, string? httpProxyUrl = null, bool httpProxyStrictSSL = true) {
|
||||||
AppClientId = appClientId;
|
AppClientId = appClientId;
|
||||||
AppName = appName;
|
AppName = appName;
|
||||||
CacheFolderPath = cacheFolderPath;
|
CacheFolderPath = cacheFolderPath;
|
||||||
CacheFileName = cacheFileName;
|
CacheFileName = cacheFileName;
|
||||||
|
HttpProxyUrl = httpProxyUrl;
|
||||||
|
HttpProxyStrictSSL = httpProxyStrictSSL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Security;
|
||||||
|
using Microsoft.Identity.Client;
|
||||||
|
using SqlToolsLogger = Microsoft.SqlTools.Utility.Logger;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.Authentication.Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implements Http Client Factory for Microsoft Identity Client to support proxy authentication.
|
||||||
|
/// </summary>
|
||||||
|
public class HttpClientProxyFactory : IMsalHttpClientFactory
|
||||||
|
{
|
||||||
|
private readonly HttpClient s_httpClient;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default constructor to construct instance with proxy URL provided.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="proxyUrl">Proxy URL to be used for network access.</param>
|
||||||
|
/// <param name="proxyStrictSSL">Whether or not proxy server certficate must be strictly validated.</param>
|
||||||
|
public HttpClientProxyFactory(string? proxyUrl, bool proxyStrictSSL)
|
||||||
|
{
|
||||||
|
if (proxyUrl != null)
|
||||||
|
{
|
||||||
|
var webProxy = new WebProxy(
|
||||||
|
new Uri(proxyUrl),
|
||||||
|
BypassOnLocal: false);
|
||||||
|
|
||||||
|
var proxyHttpClientHandler = new HttpClientHandler
|
||||||
|
{
|
||||||
|
Proxy = webProxy,
|
||||||
|
UseProxy = true,
|
||||||
|
ServerCertificateCustomValidationCallback = (request, certs, chain, policyErrors) =>
|
||||||
|
{
|
||||||
|
if (policyErrors != SslPolicyErrors.None)
|
||||||
|
{
|
||||||
|
SqlToolsLogger.Error("Proxy Server Certificate Validation failed with error: " + policyErrors.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proxyStrictSSL)
|
||||||
|
{
|
||||||
|
return policyErrors != SslPolicyErrors.None;
|
||||||
|
}
|
||||||
|
// Bypass Proxy server certificate validation.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SqlToolsLogger.Information("Proxy Server Certificate Validation bypassed as requested.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
s_httpClient = new HttpClient(proxyHttpClientHandler);
|
||||||
|
SqlToolsLogger.Verbose($"Received Http Proxy URL is used to instantiate HttpClientFactory");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s_httpClient = new HttpClient();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets Http Client instance
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public HttpClient GetHttpClient()
|
||||||
|
{
|
||||||
|
return s_httpClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -70,6 +70,12 @@ namespace Microsoft.SqlTools.Utility
|
|||||||
case "-help":
|
case "-help":
|
||||||
ShouldExit = true;
|
ShouldExit = true;
|
||||||
return;
|
return;
|
||||||
|
case "-http-proxy-url":
|
||||||
|
HttpProxyUrl = args[++i];
|
||||||
|
break;
|
||||||
|
case "-http-proxy-strict-ssl":
|
||||||
|
HttpProxyStrictSSL = true;
|
||||||
|
break;
|
||||||
case "-service-name":
|
case "-service-name":
|
||||||
ServiceName = args[++i];
|
ServiceName = args[++i];
|
||||||
break;
|
break;
|
||||||
@@ -136,6 +142,16 @@ namespace Microsoft.SqlTools.Utility
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Locale { get; private set; }
|
public string Locale { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Custom Http Proxy URL as specified in Azure Data Studio
|
||||||
|
/// </summary>
|
||||||
|
public string? HttpProxyUrl { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies whether the proxy server certificate should be verified against the list of supplied CAs.
|
||||||
|
/// </summary>
|
||||||
|
public bool HttpProxyStrictSSL { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name of service that is receiving command options
|
/// Name of service that is receiving command options
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1190,7 +1190,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
var cachePath = Path.Combine(applicationPath, applicationName, AzureTokenFolder);
|
var cachePath = Path.Combine(applicationPath, applicationName, AzureTokenFolder);
|
||||||
return new Authenticator(new(ApplicationClientId, applicationName, cachePath, MsalCacheName), () => this.encryptionKeys);
|
return new Authenticator(new(ApplicationClientId, applicationName, cachePath, MsalCacheName, commandOptions.HttpProxyUrl, commandOptions.HttpProxyStrictSSL), () => this.encryptionKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task HandleEncryptionKeysNotificationEvent(EncryptionKeysChangeParams @params, EventContext context)
|
private Task HandleEncryptionKeysNotificationEvent(EncryptionKeysChangeParams @params, EventContext context)
|
||||||
|
|||||||
@@ -302,11 +302,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
|||||||
((DatabaseInfo)databaseViewInfo.ObjectInfo).IsFilesTabSupported = true;
|
((DatabaseInfo)databaseViewInfo.ObjectInfo).IsFilesTabSupported = true;
|
||||||
((DatabaseInfo)databaseViewInfo.ObjectInfo).Filegroups = GetFileGroups(smoDatabase, databaseViewInfo);
|
((DatabaseInfo)databaseViewInfo.ObjectInfo).Filegroups = GetFileGroups(smoDatabase, databaseViewInfo);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (prototype is DatabasePrototype160)
|
if (prototype is DatabasePrototype160)
|
||||||
{
|
{
|
||||||
((DatabaseInfo)databaseViewInfo.ObjectInfo).IsLedgerDatabase = smoDatabase.IsLedger;
|
((DatabaseInfo)databaseViewInfo.ObjectInfo).IsLedgerDatabase = smoDatabase.IsLedger;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
databaseScopedConfigurationsCollection = smoDatabase.IsSupportedObject<DatabaseScopedConfiguration>() ? smoDatabase.DatabaseScopedConfigurations : null;
|
databaseScopedConfigurationsCollection = smoDatabase.IsSupportedObject<DatabaseScopedConfiguration>() ? smoDatabase.DatabaseScopedConfigurations : null;
|
||||||
databaseViewInfo.FileTypesOptions = displayFileTypes.Values.ToArray();
|
databaseViewInfo.FileTypesOptions = displayFileTypes.Values.ToArray();
|
||||||
|
|||||||
Reference in New Issue
Block a user