snowflake-connector-net: SNOW-352097: ExternalBrowser authentication type does not work for .NET Core projects on Windows, Linux or Mac
Issue Description
When using ExternalBrowser authentication type, URL to the SSO provider is constructed and a browser window is opened using default OS browser. The code to start it is in Snowflake.Data.Core.Authenticator.ExternalBrowserAuthenticator.StartBrowser https://github.com/snowflakedb/snowflake-connector-net/blob/master/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs#L156-L174
private static void StartBrowser(string url)
{
// The following code is learnt from https://brockallen.com/2016/09/24/process-start-for-urls-on-net-core/
#if NETFRAMEWORK
// .net standard would pass here
Process.Start(url);
#else
// hack because of this: https://github.com/dotnet/corefx/issues/10361
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
url = url.Replace("&", "^&");
Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true });
}
else
{
throw new SnowflakeDbException(SFError.UNSUPPORTED_PLATFORM);
}
#endif
}
The logic of the https://github.com/snowflakedb/snowflake-connector-net/blob/master/Snowflake.Data/Core/Authenticator/ExternalBrowserAuthenticator.cs#L159 is incorrect.
The NETFRAMEWORK preprocessor symbol is used to conditionally compile in Process.Start(url) for what the comments suggest are .NET Standard.
#if NETFRAMEWORK
// .net standard would pass here
Process.Start(url);
However, per https://docs.microsoft.com/en-us/dotnet/standard/frameworks#how-to-specify-a-target-framework, NETFRAMEWORK preprocessor symbol is for “.NET Framework”, not 'NET Standard".
Looking at Result of Compilation
When compiled, the DLL in the C:\snowflake\snowflake-connector-net\Snowflake.Data\bin\Release\net472\Snowflake.Data.dll as well as in the public nuget package C:\Users\Daniel\Downloads\snowflake.data.2.0.0\lib\net472\Snowflake.Data.dll that is targeting .NET Full Framework for Windows Only desktops, which works fine on Windows:
// Snowflake.Data.Core.Authenticator.ExternalBrowserAuthenticator
using System.Diagnostics;
private static void StartBrowser(string url)
{
Process.Start(url);
}
Looking at the DLL that targets .NET Core in C:\snowflake\snowflake-connector-net\Snowflake.Data\bin\Release\netstandard2.0\Snowflake.Data.dll and in C:\Users\Daniel\Downloads\snowflake.data.2.0.0\lib\netstandard2.0\Snowflake.Data.dll, that would be used by code running on Mac and Linux, we can see that code that could only run on Windows (and it does run beautifully there), but throws an SnowflakeDbException for Mac and Linux:
// Snowflake.Data.Core.Authenticator.ExternalBrowserAuthenticator
using Snowflake.Data.Client;
using System.Diagnostics;
using System.Runtime.InteropServices;
private static void StartBrowser(string url)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
url = url.Replace("&", "^&");
Process.Start(new ProcessStartInfo("cmd", $"/c start {url}")
{
CreateNoWindow = true
});
return;
}
throw new SnowflakeDbException(SFError.UNSUPPORTED_PLATFORM);
}
Possible Solution 1
This seems like an honest mistake, and can most easily be fixed by changing to correct preprocessor symbol NETSTANDARD2_1 or better yet NET:
#if NET
// .net standard would pass here
Process.Start(url);
Possible Solution 2
Better yet, change the code to explicitly address 3 different OS versions. In fact https://brockallen.com/2016/09/24/process-start-for-urls-on-net-core/ that is mentioned in comments does just that.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 15 (4 by maintainers)
Commits related to this issue
- Removed explicitly defined 'NETFRAMEWORK' preprocessor symbol from csproj; this fixes #308 and #536 NETFRAMEWORK is a standard preprocessor symbol that is already defined for builds that target .NET ... — committed to colgreen-payroc/snowflake-connector-net by colgreen-payroc a year ago
- Removed redundant 'NETFRAMEWORK' preprocessor symbol from csproj (#575) Removed redundant 'NETFRAMEWORK' preprocessor symbol from csproj; this fixes #308 and #536 NETFRAMEWORK is a standard prepr... — committed to snowflakedb/snowflake-connector-net by colgreen-payroc a year ago
I can confirm after debugging the failure to open a browser window on my Windows/dotnet core application
This is still an issue. I’ve had to manually edit the source code to get this to work on my machine. It’s an easy fix so is there any idea when this will go in?
An opportunity is being missed here in my opinion. This is a security issue (it’s important to be able to use non-password based workflows during development, being able to rely on the developers’ enterprise identity while experiments are being crafted).
The fix to this issue is being served up on a silver platter via the PR. It’s too bad this couldn’t be gotten into the most recent release.
I am currently downloading source, applying the fix (a trivial 10 second edit) and making a custom Visual Studio project available inhouse so that people can set a dependency to that project. All of this, instead of simply using the NuGet dependency. If somebody could check this out, there is a high degree of probability that externalbrowser authentication would be working in .Net 6 within a few hours of sanity check testing.
If this fix gets completed, it greatly improves the enterprise value of the connector.
@davidhcar: @colgreen-payroc has already posted a PR link above: https://github.com/snowflakedb/snowflake-connector-net/pull/575. Great minds think alike. I looked at #592 and you and Colin have analyzed it down to the same basic cause. Colin’s PR removes a preprocessor symbol from the csproj file to fix.
I can confirm that .Net 6 is not working with externalbrowser authentication: I am getting the same exception. Please consider expediting review of the PR by @colgreen-payroc above, @sfc-gh-dodievich @sfc-gh-hkapre @sfc-gh-jfan @sfc-gh-aaarora @sfc-gh-aaggarwal We may be a essentially one line fix away from being able to use .NET 6 with sso. Happening with Snowflake.Data Nuget package 2.0.20. Update: I was able to apply @colgreen-payroc fix (the commit in the PR), deleting the three lines from the csproj file, and it immediately made sso authentication work.