Skip to content

Commit cd2078d

Browse files
SNOW-1226614: Add parameter to disable SAML url check (#983)
### Description Add parameter to disable SAML url check ### Checklist - [ ] Code compiles correctly - [ ] Code is formatted according to [Coding Conventions](../blob/master/CodingConventions.md) - [ ] Created tests which fail without the change (if possible) - [ ] All tests passing (`dotnet test`) - [ ] Extended the README / documentation, if necessary - [ ] Provide JIRA issue id (if possible) or GitHub issue id in PR name
1 parent d1dad1c commit cd2078d

File tree

7 files changed

+111
-17
lines changed

7 files changed

+111
-17
lines changed

Snowflake.Data.Tests/UnitTests/SFOktaTest.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,51 @@ public void TestCorrectPostbackUrlAsync()
125125
}
126126
}
127127

128+
[Test]
129+
public void TestDoesNotThrowErrorForWrongPostbackUrlWhenCheckIsDisabled()
130+
{
131+
try
132+
{
133+
var restRequester = new Mock.MockOktaRestRequester()
134+
{
135+
TokenUrl = "https://snowflakecomputing.okta.com/api/v1/sessions?additionalFields=cookieToken",
136+
SSOUrl = "https://snowflakecomputing.okta.com/app/snowflake_testaccountdev_1/blah/sso/saml",
137+
ResponseContent = wrongPostbackContent,
138+
MaxRetryCount = MaxRetryCount,
139+
MaxRetryTimeout = MaxRetryTimeout
140+
};
141+
var sfSession = new SFSession("disable_saml_url_check=true;account=test;user=test;password=test;authenticator=https://snowflakecomputing.okta.com;host=test", null, restRequester);
142+
sfSession.Open();
143+
}
144+
catch (SnowflakeDbException e)
145+
{
146+
Assert.Fail("Should pass without exception", e);
147+
}
148+
}
149+
150+
[Test]
151+
public void TestDoesNotThrowErrorForWrongPostbackUrlWhenCheckIsDisabledAsync()
152+
{
153+
try
154+
{
155+
var restRequester = new Mock.MockOktaRestRequester()
156+
{
157+
TokenUrl = "https://snowflakecomputing.okta.com/api/v1/sessions?additionalFields=cookieToken",
158+
SSOUrl = "https://snowflakecomputing.okta.com/app/snowflake_testaccountdev_1/blah/sso/saml",
159+
ResponseContent = wrongPostbackContent,
160+
MaxRetryCount = MaxRetryCount,
161+
MaxRetryTimeout = MaxRetryTimeout
162+
};
163+
var sfSession = new SFSession("disable_saml_url_check=true;account=test;user=test;password=test;authenticator=https://snowflakecomputing.okta.com;host=test", null, restRequester);
164+
Task connectTask = sfSession.OpenAsync(CancellationToken.None);
165+
connectTask.Wait();
166+
}
167+
catch (SnowflakeDbException e)
168+
{
169+
Assert.Fail("Should pass without exception", e);
170+
}
171+
}
172+
128173
[Test]
129174
public void TestLoginRequestToString()
130175
{

Snowflake.Data.Tests/UnitTests/SFSessionPropertyTest.cs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (c) 2019 Snowflake Computing Inc. All rights reserved.
33
*/
44

@@ -139,6 +139,21 @@ public void TestValidateSupportEscapedQuotesInsideValuesForObjectProperties(stri
139139
Assert.AreEqual(expectedValue, properties[sessionProperty]);
140140
}
141141

142+
[Test]
143+
[TestCase("true")]
144+
[TestCase("false")]
145+
public void TestValidateDisableSamlUrlCheckProperty(string expectedDisableSamlUrlCheck)
146+
{
147+
// arrange
148+
var connectionString = $"ACCOUNT=account;USER=test;PASSWORD=test;DISABLE_SAML_URL_CHECK={expectedDisableSamlUrlCheck}";
149+
150+
// act
151+
var properties = SFSessionProperties.ParseConnectionString(connectionString, null);
152+
153+
// assert
154+
Assert.AreEqual(expectedDisableSamlUrlCheck, properties[SFSessionProperty.DISABLE_SAML_URL_CHECK]);
155+
}
156+
142157
public static IEnumerable<TestCase> ConnectionStringTestCases()
143158
{
144159
string defAccount = "testaccount";
@@ -194,7 +209,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
194209
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
195210
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
196211
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
197-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
212+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
213+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
198214
}
199215
};
200216

@@ -229,7 +245,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
229245
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
230246
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
231247
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
232-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
248+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
249+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
233250
}
234251
};
235252
var testCaseWithProxySettings = new TestCase()
@@ -266,7 +283,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
266283
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
267284
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
268285
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
269-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
286+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
287+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
270288
},
271289
ConnectionString =
272290
$"ACCOUNT={defAccount};USER={defUser};PASSWORD={defPassword};useProxy=true;proxyHost=proxy.com;proxyPort=1234;nonProxyHosts=localhost"
@@ -305,7 +323,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
305323
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
306324
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
307325
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
308-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
326+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
327+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
309328
},
310329
ConnectionString =
311330
$"ACCOUNT={defAccount};USER={defUser};PASSWORD={defPassword};proxyHost=proxy.com;proxyPort=1234;nonProxyHosts=localhost"
@@ -343,7 +362,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
343362
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
344363
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
345364
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
346-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
365+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
366+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
347367
}
348368
};
349369
var testCaseWithIncludeRetryReason = new TestCase()
@@ -378,7 +398,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
378398
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
379399
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
380400
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
381-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
401+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
402+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
382403
}
383404
};
384405
var testCaseWithDisableQueryContextCache = new TestCase()
@@ -412,7 +433,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
412433
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
413434
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
414435
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
415-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
436+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
437+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
416438
},
417439
ConnectionString =
418440
$"ACCOUNT={defAccount};USER={defUser};PASSWORD={defPassword};DISABLEQUERYCONTEXTCACHE=true"
@@ -448,7 +470,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
448470
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
449471
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
450472
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
451-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
473+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
474+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
452475
},
453476
ConnectionString =
454477
$"ACCOUNT={defAccount};USER={defUser};PASSWORD={defPassword};DISABLE_CONSOLE_LOGIN=false"
@@ -486,7 +509,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
486509
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
487510
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
488511
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
489-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
512+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
513+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
490514
}
491515
};
492516
var testCaseUnderscoredAccountName = new TestCase()
@@ -521,7 +545,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
521545
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
522546
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
523547
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
524-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
548+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
549+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
525550
}
526551
};
527552
var testCaseUnderscoredAccountNameWithEnabledAllowUnderscores = new TestCase()
@@ -556,7 +581,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
556581
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
557582
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
558583
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
559-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
584+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
585+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
560586
}
561587
};
562588
var testQueryTag = "Test QUERY_TAG 12345";
@@ -593,7 +619,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
593619
{ SFSessionProperty.CHANGEDSESSION, DefaultValue(SFSessionProperty.CHANGEDSESSION) },
594620
{ SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT, DefaultValue(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT) },
595621
{ SFSessionProperty.EXPIRATIONTIMEOUT, DefaultValue(SFSessionProperty.EXPIRATIONTIMEOUT) },
596-
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) }
622+
{ SFSessionProperty.POOLINGENABLED, DefaultValue(SFSessionProperty.POOLINGENABLED) },
623+
{ SFSessionProperty.DISABLE_SAML_URL_CHECK, DefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK) }
597624
}
598625
};
599626

Snowflake.Data/Core/Authenticator/OktaAuthenticator.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,14 @@ async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken)
8484
samlRawResponse = await session.restRequester.GetAsync(samlRestRequest, cancellationToken).ConfigureAwait(false);
8585
_rawSamlTokenHtmlString = await samlRawResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
8686
s_logger.Debug("step 5: Verify postback URL in SAML response");
87-
VerifyPostbackUrl();
87+
if (!session._disableSamlUrlCheck)
88+
{
89+
VerifyPostbackUrl();
90+
}
91+
else
92+
{
93+
s_logger.Debug("The saml url check is disabled. Skipping step 5");
94+
}
8895

8996
s_logger.Debug("step 6: Send SAML response to Snowflake to login");
9097
await LoginAsync(cancellationToken).ConfigureAwait(false);
@@ -139,7 +146,14 @@ void IAuthenticator.Authenticate()
139146
_rawSamlTokenHtmlString = Task.Run(async () => await samlRawResponse.Content.ReadAsStringAsync().ConfigureAwait(false)).Result;
140147

141148
s_logger.Debug("step 5: Verify postback URL in SAML response");
142-
VerifyPostbackUrl();
149+
if (!session._disableSamlUrlCheck)
150+
{
151+
VerifyPostbackUrl();
152+
}
153+
else
154+
{
155+
s_logger.Debug("The saml url check is disabled. Skipping step 5");
156+
}
143157

144158
s_logger.Debug("step 6: Send SAML response to Snowflake to login");
145159
Login();

Snowflake.Data/Core/Session/SFSession.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ public class SFSession
8787

8888
private string _user;
8989

90+
internal bool _disableSamlUrlCheck;
91+
9092
public bool GetPooling() => _poolConfig.PoolingEnabled;
9193

9294
public void SetPooling(bool isEnabled)
@@ -187,6 +189,7 @@ internal SFSession(
187189
properties.TryGetValue(SFSessionProperty.QUERY_TAG, out _queryTag);
188190
_maxRetryCount = extractedProperties.maxHttpRetries;
189191
_maxRetryTimeout = extractedProperties.retryTimeout;
192+
_disableSamlUrlCheck = extractedProperties._disableSamlUrlCheck;
190193
}
191194
catch (SnowflakeDbException e)
192195
{

Snowflake.Data/Core/Session/SFSessionHttpClientProperties.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ internal class SFSessionHttpClientProperties
3333
internal int maxHttpRetries;
3434
internal bool includeRetryReason;
3535
internal SFSessionHttpClientProxyProperties proxyProperties;
36+
internal bool _disableSamlUrlCheck;
3637
private int _maxPoolSize;
3738
private int _minPoolSize;
3839
private ChangedSessionBehavior _changedSession;
@@ -243,7 +244,8 @@ public SFSessionHttpClientProperties ExtractProperties(SFSessionProperties prope
243244
_changedSession = ExtractChangedSession(extractor, SFSessionProperty.CHANGEDSESSION),
244245
_waitingForSessionIdleTimeout = extractor.ExtractTimeout(SFSessionProperty.WAITINGFORIDLESESSIONTIMEOUT),
245246
_expirationTimeout = extractor.ExtractTimeout(SFSessionProperty.EXPIRATIONTIMEOUT),
246-
_poolingEnabled = extractor.ExtractBooleanWithDefaultValue(SFSessionProperty.POOLINGENABLED)
247+
_poolingEnabled = extractor.ExtractBooleanWithDefaultValue(SFSessionProperty.POOLINGENABLED),
248+
_disableSamlUrlCheck = extractor.ExtractBooleanWithDefaultValue(SFSessionProperty.DISABLE_SAML_URL_CHECK)
247249
};
248250
}
249251

Snowflake.Data/Core/Session/SFSessionProperty.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ internal enum SFSessionProperty
110110
[SFSessionPropertyAttr(required = false, defaultValue = "60m")]
111111
EXPIRATIONTIMEOUT,
112112
[SFSessionPropertyAttr(required = false, defaultValue = "true")]
113-
POOLINGENABLED
113+
POOLINGENABLED,
114+
[SFSessionPropertyAttr(required = false, defaultValue = "false")]
115+
DISABLE_SAML_URL_CHECK
114116
}
115117

116118
class SFSessionPropertyAttr : Attribute

0 commit comments

Comments
 (0)