Skip to content
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-1825482: PAT + OAuth Authorization Code + OAuth Client Credentials support #1978

Open
wants to merge 35 commits into
base: master
Choose a base branch
from

Conversation

sfc-gh-dheyman
Copy link
Contributor

@sfc-gh-dheyman sfc-gh-dheyman commented Nov 30, 2024

Overview

SNOW-1825482: PAT + OAuth Authorization Code + OAuth Client Credentials support

Pre-review self checklist

  • PR branch is updated with all the changes from master branch
  • The code is correctly formatted (run mvn -P check-style validate)
  • New public API is not unnecessary exposed (run mvn verify and inspect target/japicmp/japicmp.html)
  • The pull request name is prefixed with SNOW-XXXX:
  • Code is in compliance with internal logging requirements

External contributors - please answer these questions before submitting a pull request. Thanks!

  1. What GitHub issue is this PR addressing? Make sure that there is an accompanying issue to your PR.

    Issue: #NNNN

  2. Fill out the following pre-review checklist:

    • I am adding a new automated test(s) to verify correctness of my new code
    • I am adding new logging messages
    • I am modifying authorization mechanisms
    • I am adding new credentials
    • I am modifying OCSP code
    • I am adding a new dependency or upgrading an existing one
    • I am adding new public/protected component not marked with @SnowflakeJdbcInternalApi (note that public/protected methods/fields in classes marked with this annotation are already internal)
  3. Please describe how your code solves the related issue.

    Please write a short description of how your code change solves the related issue.

@sfc-gh-dheyman sfc-gh-dheyman marked this pull request as ready for review December 4, 2024 15:12
@sfc-gh-dheyman sfc-gh-dheyman requested a review from a team as a code owner December 4, 2024 15:12
@sfc-gh-dheyman sfc-gh-dheyman changed the title OAuth Authorization Code flow using Nimbus OAuth 2.0 SDK SNOW-1825482: OAuth Authorization Code flow (Snowflake + Okta) Dec 4, 2024
@snowflakedb snowflakedb deleted a comment from gitguardian bot Dec 4, 2024
Copy link

gitguardian bot commented Dec 4, 2024

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

ci/scripts/check_content.sh Outdated Show resolved Hide resolved
parent-pom.xml Show resolved Hide resolved
src/main/java/net/snowflake/client/core/SFLoginInput.java Outdated Show resolved Hide resolved
TokenRequest request = buildTokenRequest(loginInput, authorizationCode, pkceVerifier);
URI requestUri = request.getEndpointURI();
logger.debug(
"Requesting access token from: " + requestUri.getAuthority() + requestUri.getPath());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use logger parameters instead of string concatenation, also in other logs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

@sfc-gh-jszczerbinski sfc-gh-jszczerbinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me in general, I will need a second look once I get some more knowledge about OAuth

@@ -29,6 +29,12 @@ public enum SFSessionProperty {
AUTHENTICATOR("authenticator", false, String.class),
OKTA_USERNAME("oktausername", false, String.class),
PRIVATE_KEY("privateKey", false, PrivateKey.class),
OAUTH_REDIRECT_URI("redirectUri", false, String.class),
CLIENT_ID("clientID", false, String.class),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oauthClientId, oauthClientSecret etc.?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer not to introduce new parameters, after all user can use only one authentication type at a time

},
"bodyPatterns": [
{
"contains": "grant_type=authorization_code&code=123&redirect_uri=http%3A%2F%2Flocalhost%3A8001%2Fsnowflake%2Foauth-redirect&code_verifier="
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please verify if we indeed use PKCE

Copy link
Contributor Author

@sfc-gh-dheyman sfc-gh-dheyman Dec 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we need to.

/*
* Authorization code flow with browser popup
*/
OAUTH_AUTHORIZATION_CODE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe CLIENT_OAUTH would be a good name from this OAuth flows to make it different than OAuth and indicate it's on client side, WDYT? @sfc-gh-dprzybysz @sfc-gh-dheyman @sfc-gh-pfus

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like it. CLIENT_OAUTH is too generic. Dawid's name seems better to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather change the original OAUTH authenticator to OAUTH_ACCESS_TOKEN or something like that, but I understand it would be a BCR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sfc-gh-eworoshow WDYT? did you go through any naming discussion already

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a couple options:

  1. AUTHENTICATOR=OAUTH plus OAUTH_FLOW={TOKEN | AUTHORIZATION_CODE | CLIENT_CREDENTIALS }, where TOKEN is our existing default.
  2. AUTHENTICATOR={OAUTH | OAUTH_ACCESS_TOKEN, alias of OAUTH | OAUTH_AUTHORIZATION_CODE | ... }.

In both cases I think we should use the "standard" name for the OAuth flow we're implementing.

linkage-checker-exclusion-rules.xml Outdated Show resolved Hide resolved
/*
* Authorization code flow with browser popup
*/
OAUTH_AUTHORIZATION_CODE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like it. CLIENT_OAUTH is too generic. Dawid's name seems better to me.

@sfc-gh-dheyman sfc-gh-dheyman changed the title SNOW-1825482: OAuth Authorization Code flow (Snowflake + Okta) SNOW-1825482: PAT + OAuth Authorization Code + OAuth Client Credentials support Dec 10, 2024
Copy link

@sfc-gh-eworoshow sfc-gh-eworoshow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't review the whole PR, I just wanted to opine on a couple points I learned about indirectly 🙂

private static final SFLogger logger =
SFLoggerFactory.getLogger(OAuthAuthorizationCodeAccessTokenProvider.class);

private static final String DEFAULT_REDIRECT_HOST = "http://localhost:8001";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use http://127.0.0.1 for compliance with RFC 8252 which strongly recommends not listening on localhost but rather on the IPv4 loopback interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, had no idea about this. Will adjust.

SFLoggerFactory.getLogger(OAuthAuthorizationCodeAccessTokenProvider.class);

private static final String DEFAULT_REDIRECT_HOST = "http://localhost:8001";
private static final String REDIRECT_URI_ENDPOINT = "/snowflake/oauth-redirect";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should perhaps omit the path here, since I want the Snowflake OAuth "driver" OAuth integration to work more straightforwardly for other use cases (e.g., customer code)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea.

src/main/java/net/snowflake/client/core/SFLoginInput.java Outdated Show resolved Hide resolved
OAuthAccessTokenProviderFactory accessTokenProviderFactory =
new OAuthAccessTokenProviderFactory(
new SessionUtilExternalBrowser.DefaultAuthExternalBrowserHandlers(),
(int) loginInput.getBrowserResponseTimeout().getSeconds());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could change the type in OAuthAccessTokenProviderFactory (and down the line) to be long? From what I understand this parameter is only ever used cast to long either way.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the changes made, this cast is unnecessary

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants