Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
40033cf
adding new AuthHttpServer class
sfc-gh-mkeller Jan 14, 2025
3b07b8e
unrelated simplifications
sfc-gh-mkeller Jan 14, 2025
385f763
adding new oauth code flow implementation
sfc-gh-mkeller Jan 14, 2025
ac7cded
adding new TODO
sfc-gh-mkeller Jan 14, 2025
2a4456c
adding changelog entry
sfc-gh-mkeller Jan 14, 2025
ee45f2d
making oauth state random
sfc-gh-mkeller Jan 14, 2025
f39e952
make client_secret optional
sfc-gh-mkeller Jan 15, 2025
8fde1fc
make state check failure fail auth
sfc-gh-mkeller Jan 15, 2025
6d025e5
switch to cryptographically-secure source
sfc-gh-mkeller Jan 16, 2025
54e7833
redo connection parameters based on feedback
sfc-gh-mkeller Jan 24, 2025
d8edbf7
some string updates
sfc-gh-mkeller Jan 27, 2025
5275879
add Authorization header to token request
sfc-gh-mkeller Jan 27, 2025
4d71f0c
fix logging bug
sfc-gh-mkeller Jan 29, 2025
a887c29
review feedback
sfc-gh-mkeller Jan 29, 2025
a20dd97
rewording parameters based on discussion
sfc-gh-mkeller Jan 29, 2025
4d78183
reworking the defaut oauth scope
sfc-gh-mkeller Jan 29, 2025
60b461a
adding port support into oauth code flow auth
sfc-gh-mkeller Jan 29, 2025
f9214a7
implement PKCE
sfc-gh-mkeller Jan 16, 2025
81627af
review feedback
sfc-gh-mkeller Jan 30, 2025
adc1380
adding new AuthHttpServer class
sfc-gh-mkeller Jan 14, 2025
cdc3fc0
unrelated simplifications
sfc-gh-mkeller Jan 14, 2025
7dfd201
adding new oauth code flow implementation
sfc-gh-mkeller Jan 14, 2025
c9d0453
adding new TODO
sfc-gh-mkeller Jan 14, 2025
0c6841a
adding changelog entry
sfc-gh-mkeller Jan 14, 2025
2ff5e8f
making oauth state random
sfc-gh-mkeller Jan 14, 2025
4d8d214
make client_secret optional
sfc-gh-mkeller Jan 15, 2025
a8edcb7
make state check failure fail auth
sfc-gh-mkeller Jan 15, 2025
38564b1
switch to cryptographically-secure source
sfc-gh-mkeller Jan 16, 2025
24308f3
redo connection parameters based on feedback
sfc-gh-mkeller Jan 24, 2025
1ad5185
some string updates
sfc-gh-mkeller Jan 27, 2025
301438a
add Authorization header to token request
sfc-gh-mkeller Jan 27, 2025
fccfcb2
fix logging bug
sfc-gh-mkeller Jan 29, 2025
8dbfdf0
review feedback
sfc-gh-mkeller Jan 29, 2025
c07689b
rewording parameters based on discussion
sfc-gh-mkeller Jan 29, 2025
eeda415
reworking the defaut oauth scope
sfc-gh-mkeller Jan 29, 2025
ea0bff2
adding port support into oauth code flow auth
sfc-gh-mkeller Jan 29, 2025
6b3bd63
do not log state
sfc-gh-mkeller Jan 31, 2025
a850492
Update src/snowflake/connector/connection.py
sfc-gh-mkeller Feb 3, 2025
d5de908
Merge branch 'mkeller/SNOW-1825621/oauth-code-flow-support' into mkel…
sfc-gh-mmishchenko Feb 12, 2025
70f1ce1
adding new AuthHttpServer class
sfc-gh-mkeller Jan 14, 2025
85937f1
unrelated simplifications
sfc-gh-mkeller Jan 14, 2025
f2e0f6e
adding new oauth code flow implementation
sfc-gh-mkeller Jan 14, 2025
3649a20
adding new TODO
sfc-gh-mkeller Jan 14, 2025
fa99a3c
adding changelog entry
sfc-gh-mkeller Jan 14, 2025
33dc5af
making oauth state random
sfc-gh-mkeller Jan 14, 2025
60fb3db
make client_secret optional
sfc-gh-mkeller Jan 15, 2025
df0d8e5
make state check failure fail auth
sfc-gh-mkeller Jan 15, 2025
9fa8b01
switch to cryptographically-secure source
sfc-gh-mkeller Jan 16, 2025
a743a81
redo connection parameters based on feedback
sfc-gh-mkeller Jan 24, 2025
43c2e4f
some string updates
sfc-gh-mkeller Jan 27, 2025
7434b85
add Authorization header to token request
sfc-gh-mkeller Jan 27, 2025
b08f346
fix logging bug
sfc-gh-mkeller Jan 29, 2025
5d2d602
review feedback
sfc-gh-mkeller Jan 29, 2025
e265a51
rewording parameters based on discussion
sfc-gh-mkeller Jan 29, 2025
f187ad5
reworking the defaut oauth scope
sfc-gh-mkeller Jan 29, 2025
ccb6684
adding port support into oauth code flow auth
sfc-gh-mkeller Jan 29, 2025
3b948b4
do not log state
sfc-gh-mkeller Jan 31, 2025
3fbb1ed
Update src/snowflake/connector/connection.py
sfc-gh-mkeller Feb 3, 2025
8bbbc55
Merge branch 'mkeller/SNOW-1825621/oauth-code-flow-support' into mkel…
sfc-gh-mmishchenko Feb 19, 2025
6e76857
adding new AuthHttpServer class
sfc-gh-mkeller Jan 14, 2025
c6c17d1
unrelated simplifications
sfc-gh-mkeller Jan 14, 2025
550e54c
adding new oauth code flow implementation
sfc-gh-mkeller Jan 14, 2025
f9ffa01
adding new TODO
sfc-gh-mkeller Jan 14, 2025
ff44946
adding changelog entry
sfc-gh-mkeller Jan 14, 2025
a1d9b54
making oauth state random
sfc-gh-mkeller Jan 14, 2025
fec1dca
make client_secret optional
sfc-gh-mkeller Jan 15, 2025
ff041a2
make state check failure fail auth
sfc-gh-mkeller Jan 15, 2025
3e60038
switch to cryptographically-secure source
sfc-gh-mkeller Jan 16, 2025
a85abac
redo connection parameters based on feedback
sfc-gh-mkeller Jan 24, 2025
e4549ff
some string updates
sfc-gh-mkeller Jan 27, 2025
1305df7
add Authorization header to token request
sfc-gh-mkeller Jan 27, 2025
fc6a403
fix logging bug
sfc-gh-mkeller Jan 29, 2025
638f741
review feedback
sfc-gh-mkeller Jan 29, 2025
b94eeb7
rewording parameters based on discussion
sfc-gh-mkeller Jan 29, 2025
e7e664e
reworking the defaut oauth scope
sfc-gh-mkeller Jan 29, 2025
725b3d0
adding port support into oauth code flow auth
sfc-gh-mkeller Jan 29, 2025
6b9b48c
do not log state
sfc-gh-mkeller Jan 31, 2025
acfe7e7
Update src/snowflake/connector/connection.py
sfc-gh-mkeller Feb 3, 2025
6bad2e1
SNOW-1917265: Add OAUTH_TYPE for authorization flow (#2174)
sfc-gh-pbulawa Feb 25, 2025
91eb76e
Merge branch 'mkeller/SNOW-1825621/oauth-code-flow-support' into mkel…
sfc-gh-mmishchenko Feb 25, 2025
a83d09c
Merge branch 'mkeller/SNOW-1825621/oauth-code-flow-support' into mkel…
sfc-gh-mmishchenko Mar 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/snowflake/connector/auth/oauth_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from __future__ import annotations

import base64
import hashlib
import json
import logging
import secrets
Expand Down Expand Up @@ -55,6 +56,7 @@ def __init__(
token_request_url: str,
redirect_uri: str,
scope: str,
pkce: bool = False,
**kwargs,
) -> None:
super().__init__(**kwargs)
Expand All @@ -72,6 +74,10 @@ def __init__(
logger.debug("chose oauth state: %s", "".join("*" for _ in self._state))
self._oauth_token = None
self._protocol = "http"
self.pkce = pkce
if pkce:
logger.debug("oauth pkce is going to be used")
self._verifier: str | None = None

def reset_secrets(self) -> None:
self._oauth_token = None
Expand Down Expand Up @@ -104,6 +110,18 @@ def construct_url(self) -> str:
}
if self.scope:
params["scope"] = self.scope
if self.pkce:
self._verifier = secrets.token_urlsafe(43)
# calculate challenge and verifier
challenge = (
base64.urlsafe_b64encode(
hashlib.sha256(self._verifier.encode("utf-8")).digest()
)
.decode("utf-8")
.rstrip("=")
)
params["code_challenge"] = challenge
params["code_challenge_method"] = "S256"
url_params = urllib.parse.urlencode(params)
url = f"{self.authentication_url}?{url_params}"
return url
Expand Down Expand Up @@ -186,6 +204,10 @@ def prepare(
}
if self.client_secret:
fields["client_secret"] = self.client_secret
if self.pkce:
assert self._verifier is not None
fields["code_verifier"] = self._verifier

resp = urllib3.PoolManager().request_encode_body( # TODO: use network pool to gain use of proxy settings and so on
"POST",
self.token_request_url,
Expand Down
11 changes: 10 additions & 1 deletion src/snowflake/connector/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from __future__ import annotations

import atexit
import collections.abc
import logging
import os
import pathlib
Expand Down Expand Up @@ -334,6 +335,11 @@ def _get_private_bytes_from_file(
str,
# SNOW-1825621: OAUTH implementation
),
"oauth_security_features": (
("pkce",),
collections.abc.Iterable, # of strings
# SNOW-1825621: OAUTH PKCE
),
}

APPLICATION_RE = re.compile(r"[\w\d_]+")
Expand Down Expand Up @@ -1088,7 +1094,7 @@ def __open_connection(self):
self.auth_class = AuthByWebBrowser(
application=self.application,
protocol=self._protocol,
host=self.host,
host=self.host, # TODO: delete this?
port=self.port,
timeout=self.login_timeout,
backoff_generator=self._backoff_generator,
Expand Down Expand Up @@ -1125,6 +1131,8 @@ def __open_connection(self):
backoff_generator=self._backoff_generator,
)
elif self._authenticator == OAUTH_AUTHORIZATION_CODE:
pkce = "pkce" in map(lambda e: e.lower(), self._oauth_security_features)

if self._oauth_client_id is None:
Error.errorhandler_wrapper(
self,
Expand All @@ -1150,6 +1158,7 @@ def __open_connection(self):
),
redirect_uri="http://127.0.0.1:{port}/",
scope=self._oauth_scope,
pkce=pkce,
)
elif self._authenticator == USR_PWD_MFA_AUTHENTICATOR:
self._session_parameters[PARAMETER_CLIENT_REQUEST_MFA_TOKEN] = (
Expand Down