-
Notifications
You must be signed in to change notification settings - Fork 1
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
Update login method as Snowflake changed the OAuth response #46
Update login method as Snowflake changed the OAuth response #46
Conversation
1. Allow redirects from GET requests 2. Get cookies from all responses 3. Workaround for the issue that the API now returns the client_id in the URL, and the apiGET function doesn't return the URL. So we need to return the final redirected URL as the result for `start-oauth/snowflake`. Tested username+password and SSO.
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.
Duplicate &
in URL looks like a typo, see inline comment.
I don't have the relevant dev tools so can't test these changes myself.
Thanks for the effort!
|
||
Tuple<string, List<string>, HttpStatusCode> result = apiGET( | ||
appServerUrl, | ||
String.Format("start-oauth/snowflake?accountUrl={0}&state={1}", HttpUtility.UrlEncode(accountUrl), HttpUtility.UrlEncode(stateParam)), | ||
String.Format("start-oauth/snowflake?accountUrl={0}&&state={1}", HttpUtility.UrlEncode(accountUrl), HttpUtility.UrlEncode(stateParam)), |
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.
may want to remove duplicate & from URL
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 is what Snowflake sends back, we should make a note it's not a typo.
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've updated this with some more contextual documentation around &&state
- great pickup, as this IS confusing! 😕
When a user logs in via the Snowsight UI at https://app.snowflake.com, Snowflake redirects them to the start-oauth/snowflake
endpoint:
https://apps-api.c1.us-east-999.aws.app.snowflake.com/start-oauth/snowflake?accountUrl=https%3A%2F%2Faccount12345us-east-999.snowflakecomputing.com&&state=%7B%22csrf%22%3A%22abcdefab%22%2C%22url%22%3A%22https%3A%2F%2Faccount12345.us-east-999.snowflakecomputing.com%22%2C%22windowId%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22browserUrl%22%3A%22https%3A%2F%2Fapp.snowflake.com%2F%22%7D
Note that the
&&state
is not a typo, it is what Snowflake sends, so we send the same.
This string is URL-encoded; its decoded form appears as follows:
https://apps-api.c1.us-east-999.aws.app.snowflake.com/start-oauth/snowflake?accountUrl=https://account12345us-east-999.snowflakecomputing.com&&state={"csrf":"abcdefab","url":"https://account12345.us-east-999.snowflakecomputing.com","windowId":"00000000-0000-0000-0000-000000000000","browserUrl":"https://app.snowflake.com/"}
Snowflake expects the following keys in the state object:
- csrf - The csrf token from the earlier step
- url - The URL of the user's Snowflake instance (https://account12345.us-east-999.snowflakecomputing.com)
- windowId - This parameter is not needed, this parameter is the unique window ID of the user's web browser session, used to mitigate forgery risks.
- browserUrl - https://app.snowflake.com
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.
Code changes look plausible.
Compiled and tested against my Snowflake account.
This change fixed the problem for me.
@lziegler @joshuataylor I can accept this pull request, but I need to ask you both to acknowledge the Snowflake Labs CLA. Please review the documentation at the following link and add your acceptance in a comment. An acceptable response would be _I accept Snowflake Open Source Contribution terms and conditions. |
I, Josh Taylor, accept Snowflake Open Source Contribution terms and conditions, signed Sunday, 21st January 2024 (2024-01-21). |
I accept Snowflake Open Source Contribution terms and conditions. |
I have access to 3 snowflake accounts, 2 behind MFA, and one just username/password.
The username/password one works fine, although I had to use the actual account name and not the account locator before it let me proceed. Thank you for fixing this! Much appreciated. |
@joshuataylor I compiled your code and it doesn't work for me. |
Try hitting |
And are you SURE you are running the code compiled from changes? Your path those 2023.2.8.0 version with binaries? |
@danielodievich I initially used the account locator and received the same error. I cloned Joshua's repo and compiled the code without updating the version in the .csproj file. That is why 2023.2.8.0 is showing. |
I tried authenticating to another account in Azure and received the same error. |
I'll sign up for some trial accounts for Azure and Google Cloud, as it seems there might be a different cookie or something needed (they might not have rolled out the feature across all clouds perhaps yet?). |
The screenshots that I shared were for an AWS account in the us west 2 region. That is the first region that Snowflake deployed their first accounts. I should have been able to authenticate. I'll keep trying. |
Could you email me your sanitised logs, the app does verbose logging (doesn't store passwords, but does store cookies, so remove those etc). joshuataylorx at gmail dot com |
May I suggest that @sfc-gh-mybarra give @joshuataylor an account in his |
I upgraded PowerShell to the latest version and ran the ZipReleases module. I'm am still receiving the same error with the newly generated binaries. I'm not sure what granting access to my account would accomplish. If all users can't compile and run, I can't approve the pull request yet. |
I think if Joshua had access to your account, he can check if his logic works in your account and debug it from there. |
That could be a solution, but how would my Enterprise Edition account with username/password differ from any other Enterprise Edition account with the same configuration? Debugging my account seems more like a bandaid measure. Additionally, would this be the solution to debug issues in other accounts? |
I think we need to take a step back and answer "When something goes wrong, how do we figure out what is going on?". E.g:
We should focus on #1 first, as this will be the most common issue - either due to user error, or Snowflake changing something on their end, adding a new authentication method etc. Authentication and other processes rarely change, especially at SF, but given this is more of an internal endpoint there will be changes. When Snowflake changes something (rare)If there is a change that Snowflake has made that breaks authentications we'll all know pretty quickly :-). I have recently setup a scheduled job which logs in using Username+Password and Private Key Auth twice a day to ensure everything is still valid for these endpoints. Login issues on the client side
I'm going to bet that most of the time it comes down to a user typing in their credentials wrong, HTTP Proxy issues (I bet Snowflake tends to be used a lot on enterprise/work computers :-)) and other transient issues that are hard to track down. We can become better at telling the user about this when it occurs, instead of a generic Login Error CodesSnowflake has done some great work to improve issues around the login process by adding better error codes for Private Keys, and then I think also MFA, OAuth and SSO. So if it is actually a user issue, then we should be able to give them a (hopefully relevant!) error code. Diagnosing IssuesWhat would be good is to have a way for a user to share detailed enough diagnosis information in a format that is both easily understandable by a non-technical user but also be able to figure out what is going on. This file should be terse enough so the user can understand that they are not going to be sharing any secrets (passwords, cookies, etc), company information, endpoint info, etc. This way we can tell if there are multiple If the user can't login, we could print the line along the lines of Short term solutionLet's come up with a short term solution, with the intention of having it another draft PR which can be used to help those who currently can't login with this PR's change. This is a quick idea dump (least amount of effort, with the intention to not merge it and come up with something better later): Scenario 1: Someone who just wants to share a quick log:
Scenario 2: More technical user who wants to provide a debug logSometimes we're going to need more information, so having a way to get the sanitised request and response URL/Headers/Body will be good. More on this to come. |
Just to be clear, I'll create a follow up PR in the next day or so, it's a long weekend here and I finally have a chance to finish this. |
That sounds great @joshuataylor. I appreciate you stepping in to help outside of your regular day to day. I'll look for the upcoming PR. |
Okay, so it looks like with release 8.4 there were some major changes made around authentication, which explains why we saw the authentication workflow break, and perhaps work for some but not others during the rollout. I'm going to guess that those who couldn't log in were either: a/ Still on the old version I know Snowflake does gradual rollouts, and some users can also request to be on the new version etc. This should hopefully be a change that isn't made often, but should be something we can hopefully adapt to if needed. I'm seeing a new authentication flow for SSO now on both my AWS US instance ( select concat('Snowflake Version: ', coalesce(current_version(), '-'), ' | Region: ', coalesce(current_region(), '-')); I'll get the code updated for this change, username/password seems to work fine still. I also have a new branch I'll push out with what I'm calling The log file output looks like this:
There is also an "Extensive Diagnostic Test" which includes Unknown Cookie Values from the request/response, as well as additional information from the response such as additional keys. |
Super annoying, I had to readd my If you have the same issue, and can reproduce it with Snowflake Connector Python, submit a support ticket. 🤷 Now 8.4 has been out for a week, I believe all accounts should be on the newest release and everything should hopefully work now. Double check with If you still have issues, please try this PR and post the |
I was testing your fix branch and I did get errors when trying to use the "regionless" url format ( org_name-account_name ) as the -Account . It did look like it was able to figure out the URL when using this format but I kept getting
when I switched to just using the account locator URL format it worked just fine. I was also able to use SSO login to an account as well. |
Interesting! Can you login normally using that format on app.snowflake.com? Is this a new login URL format? Does it pass valid on edit: Ah https://docs.snowflake.com/en/user-guide/organizations-connect explains it!
So testing for this would be good. Looks like clicking "copy" here adds a ![]() IMHO, using the values from here is what you would want to do in future. And this would be interesting to test with Snowsight |
This might also be related to https://stackoverflow.com/questions/60177963/how-can-you-connect-snowflake-to-an-ide-using-okta-with-mfa , could I ask what SSO provider you're testing with, so far I've been testing with Auth0 and it's been pretty flawless, but this is a pretty simple implementation and others might have more complex setups. I tested using <ORG_NAME>-<ACCOUNT_IDENTIFIER> for AWS & Azure, and they both seemed to work. The url and other information is gathered from the validate-url endpoint.
|
The SSO I used is OKTA . |
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 was able to use the hotfix branch and create the binaries and use them to successfully authenticate using id/pass and SSO (Okta) .
Ok @joshuataylor. @sfc-gh-sredding helped me get past the issues that I was having, and will merge your pull request. Thank you for your hard work. |
start-oauth/snowflake
.Tested username+password and SSO.
Fixes #45