-
Notifications
You must be signed in to change notification settings - Fork 138
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
SNOW-715524: Add SSO token cache #921
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #921 +/- ##
==========================================
+ Coverage 85.70% 87.23% +1.53%
==========================================
Files 117 122 +5
Lines 11331 11614 +283
Branches 1130 1158 +28
==========================================
+ Hits 9711 10132 +421
+ Misses 1342 1196 -146
- Partials 278 286 +8 ☔ View full report in Codecov by Sentry. |
…nector-net into SNOW-715524-SSO-Token-Cache
…nector-net into SNOW-715524-SSO-Token-Cache
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerFactory.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerFactory.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerAdysTechImpl.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerAdysTechImpl.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerFileImpl.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerInMemoryImpl.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerInMemoryImpl.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerInMemoryImpl.cs
Outdated
Show resolved
Hide resolved
Any updates on this PR ? Can I help ? I been waiting for this SSO Token Cache for long time |
Currently we're trying out different libraries/packages for the credential manager. Then it'll be reviewed if it meets the security requirements |
Snowflake.Data/Client/SnowflakeCredentialManager/ISnowflakeCredentialManager.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerFactory.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerFactory.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerFactory.cs
Outdated
Show resolved
Hide resolved
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerFactory.cs
Outdated
Show resolved
Hide resolved
public void SaveCredentials(string key, string token) | ||
{ | ||
s_logger.Debug($"Saving credentials into memory for key: {key}"); | ||
s_credentials[key] = SnowflakeCredentialEncryption.EncryptToken(token); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we encrypt tokens when storing them in memory whereas in file implementation we do not do it?
I think encryption here it is not necessary... Maybe only we should make sure that ToString()
operation on this class does not reveal any credentials.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I saw JDBC do some encryption so I tried to follow it
The encryption is now removed. I also checked ToString()
and it only shows the class name so no sensitive info. The dictionary itself is private so it shouldn't be possible to call ToString()
on the dictionary itself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe, you are right some kind of obfuscating the string would be good. Maybe let's use SecureString to store the tokens. You could use Snowflake.Data.Core.Tools.SecureStringHelper
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, the tokens are now stored with SecureStringHelper
Snowflake.Data/Client/SnowflakeCredentialManager/SnowflakeCredentialManagerInMemoryImpl.cs
Outdated
Show resolved
Hide resolved
|
||
namespace Snowflake.Data.Client | ||
{ | ||
public class SnowflakeCredentialManagerFactory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this class should not be public since it is not meant to be used by the user. You should move it into another package because in Snowflake.Data.Client should be only classes we want to share with the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood, the class is no longer public and has been moved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But you moved all the classes from Client to Core - I meant something else...
The Idea is that all classes which could be used by the client should be publicly accessible and located in Client package so the client has all his classes in one place. Classes in Client package start with Snowflake - so it would be good to follow this convention.
In other than Client package we have our internal classes. These should not be public. These classes do not prefix with Snowflake. Sometimes they prefix with SF, but I don't think we should prefix every our internal class with SF, because we do not gain anything from this. So for our internal classes we are free to use any name we want.
The factory class is internal so it is good that you moved it to Core. But for instance ISFCredentialManager is public so it would better fit to Client package. And its previous name ISnowflakeCredentialManager was better fitting our conventions. However the class TokenType which is defined in the same file as ISFCredentialManager is internal so it should be extracted to separate file and placed in Core. Sometimes if we would not like to put too many implementation details into the Client classes we can use a pattern of creating a wrapper class in API. Such a pattern was used here: https://github.com/snowflakedb/snowflake-connector-net/blob/master/Snowflake.Data/Client/SnowflakeDbSessionPool.cs is a public class in Client package which is wrapping the internal class in Core package: https://github.com/snowflakedb/snowflake-connector-net/blob/master/Snowflake.Data/Core/Session/SessionPool.cs
So following this pattern we could have internal implementations in Core.CredentialManager package but then we would need a publicly accessible wrappers in Client package with names starting from Snowflake. Or you can don't create such wrappers but move all public classes to Client package - it is up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake, I thought I was supposed to move the other classes as well
I've reverted some of the changes and did some refactoring:
- Rename ISFCredentialManager back to ISnowflakeCredentialManager
- Move ISnowflakeCredentialManager back to Client
- Extract TokenType from ISnowflakeCredentialManager
Does that look alright to you?
|
||
namespace Snowflake.Data.Client | ||
{ | ||
public class SnowflakeCredentialManagerNativeImpl : ISnowflakeCredentialManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could move all the implementations into subpackage Infrastructure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -252,6 +258,8 @@ private SFRestRequest BuildAuthenticatorRestRequest(int port) | |||
AccountName = session.properties[SFSessionProperty.ACCOUNT], | |||
Authenticator = AUTH_NAME, | |||
BrowserModeRedirectPort = port.ToString(), | |||
DriverName = SFEnvironment.DriverName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this improvement is not related to the feature itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not directly related, but I saw that other connectors like JDBC include the driver name and version in the request so I thought to include it as well in .NET for parity
…nector-net into SNOW-715524-SSO-Token-Cache # Conflicts: # Snowflake.Data.Tests/UnitTests/SFSessionPropertyTest.cs
…nector-net into SNOW-715524-SSO-Token-Cache
…nector-net into SNOW-715524-SSO-Token-Cache
…nector-net into SNOW-715524-SSO-Token-Cache # Conflicts: # Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs
…nector-net into SNOW-715524-SSO-Token-Cache # Conflicts: # Snowflake.Data/Core/SFError.cs
Description
Add SSO token cache
Checklist
dotnet test
)