Skip to content

Commit 52f08af

Browse files
committed
refactor!: remove dangerous *args and idtoken_model argument
idtoken_model was removed as an argument as it is enforced by pydantic with type hinting in the depends statement BREAKING CHANGE
1 parent dd6b370 commit 52f08af

File tree

4 files changed

+20
-46
lines changed

4 files changed

+20
-46
lines changed

README.md

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,15 @@ from fastapi import FastAPI
4848
from fastapi_oidc import IDToken
4949
from fastapi_oidc import get_auth
5050

51-
OIDC_config = {
52-
"client_id": "0oa1e3pv9opbyq2Gm4x7",
53-
# Audience can be omitted in which case the aud value defaults to client_id
54-
"audience": "https://yourapi.url.com/api",
51+
52+
authenticate_user = get_auth(
53+
client_id": "0oa1e3pv9opbyq2Gm4x7",
5554
"base_authorization_server_uri": "https://dev-126594.okta.com",
5655
"issuer": "dev-126594.okta.com",
57-
"signature_cache_ttl": 3600,
58-
}
59-
60-
authenticate_user: Callable = get_auth(**OIDC_config)
56+
# Audience can be omitted in which case it defaults to client_id
57+
"audience": "https://yourapi.url.com/api", # optional, verification only
58+
"signature_cache_ttl": 3600, # optional
59+
)
6160

6261
app = FastAPI()
6362

@@ -77,7 +76,7 @@ class CustomIDToken(fastapi_oidc.IDToken):
7776
custom_default: float = 3.14
7877

7978

80-
authenticate_user: Callable = get_auth(**OIDC_config, token_type=CustomIDToken)
79+
authenticate_user = get_auth(**OIDC_config)
8180

8281
app = FastAPI()
8382

fastapi_oidc/auth.py

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ def test_auth(authenticated_user: AuthenticatedUser = Depends(authenticate_user)
1717
"""
1818

1919
from typing import Callable
20+
from typing import Dict
2021
from typing import Optional
21-
from typing import Type
2222

2323
from fastapi import Depends
2424
from fastapi import HTTPException
@@ -29,19 +29,15 @@ def test_auth(authenticated_user: AuthenticatedUser = Depends(authenticate_user)
2929
from jose.exceptions import JWTClaimsError
3030

3131
from fastapi_oidc import discovery
32-
from fastapi_oidc.exceptions import TokenSpecificationError
33-
from fastapi_oidc.types import IDToken
3432

3533

3634
def get_auth(
37-
*_,
3835
client_id: str,
39-
audience: Optional[str] = None,
4036
base_authorization_server_uri: str,
4137
issuer: str,
42-
signature_cache_ttl: int,
43-
token_type: Type[IDToken] = IDToken,
44-
) -> Callable[[str], IDToken]:
38+
audience: Optional[str] = None,
39+
signature_cache_ttl: int = 3600,
40+
) -> Callable[[str], Dict]:
4541
"""Take configurations and return the authenticate_user function.
4642
4743
This function should only be invoked once at the beggining of your
@@ -63,26 +59,19 @@ def get_auth(
6359
6460
6561
Returns:
66-
func: authenticate_user(auth_header: str) -> IDToken (or token_type)
62+
func: authenticate_user(auth_header: str) -> Dict
6763
6864
Raises:
6965
Nothing intentional
7066
"""
7167

72-
if not issubclass(token_type, IDToken):
73-
raise TokenSpecificationError(
74-
"Invalid argument for token_type. "
75-
"Token type must be a subclass of fastapi_oidc.type.IDToken. "
76-
f"Received {token_type=}"
77-
)
78-
7968
oauth2_scheme = OpenIdConnect(
8069
openIdConnectUrl=f"{base_authorization_server_uri}/.well-known/openid-configuration"
8170
)
8271

8372
discover = discovery.configure(cache_ttl=signature_cache_ttl)
8473

85-
def authenticate_user(auth_header: str = Depends(oauth2_scheme)) -> IDToken:
74+
def authenticate_user(auth_header: str = Depends(oauth2_scheme)) -> Dict:
8675
"""Validate and parse OIDC ID token against issuer in config.
8776
Note this function caches the signatures and algorithms of the issuing server
8877
for signature_cache_ttl seconds.
@@ -92,7 +81,7 @@ def authenticate_user(auth_header: str = Depends(oauth2_scheme)) -> IDToken:
9281
scenes by Depends.
9382
9483
Return:
95-
IDToken (types.IDToken):
84+
Dict: Dictionary with IDToken information
9685
9786
raises:
9887
HTTPException(status_code=401, detail=f"Unauthorized: {err}")
@@ -103,7 +92,7 @@ def authenticate_user(auth_header: str = Depends(oauth2_scheme)) -> IDToken:
10392
algorithms = discover.signing_algos(OIDC_discoveries)
10493

10594
try:
106-
token = jwt.decode(
95+
return jwt.decode(
10796
id_token,
10897
key,
10998
algorithms,
@@ -112,7 +101,6 @@ def authenticate_user(auth_header: str = Depends(oauth2_scheme)) -> IDToken:
112101
# Disabled at_hash check since we aren't using the access token
113102
options={"verify_at_hash": False},
114103
)
115-
return token_type.parse_obj(token)
116104

117105
except (ExpiredSignatureError, JWTError, JWTClaimsError) as err:
118106
raise HTTPException(status_code=401, detail=f"Unauthorized: {err}")

fastapi_oidc/exceptions.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/test_auth.py

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import pytest
2-
31
from fastapi_oidc import auth
4-
from fastapi_oidc.exceptions import TokenSpecificationError
52
from fastapi_oidc.types import IDToken
63

74

@@ -18,7 +15,7 @@ def test__authenticate_user(
1815
token = token_with_audience
1916

2017
authenticate_user = auth.get_auth(**config_w_aud)
21-
id_token: IDToken = authenticate_user(auth_header=f"Bearer {token}")
18+
id_token = IDToken(**authenticate_user(auth_header=f"Bearer {token}"))
2219

2320
assert id_token.email == test_email # nosec
2421
assert id_token.aud == config_w_aud["audience"]
@@ -39,20 +36,12 @@ def test__authenticate_user_no_aud(
3936

4037
authenticate_user = auth.get_auth(**no_audience_config)
4138

42-
id_token: IDToken = authenticate_user(auth_header=f"Bearer {token}")
39+
id_token = IDToken(**authenticate_user(auth_header=f"Bearer {token}"))
4340

4441
assert id_token.email == test_email # nosec
4542
assert id_token.aud == no_audience_config["client_id"]
4643

4744

48-
def test__get_auth_raises_if_token_type_is_not_subclass_of_IDToken(no_audience_config):
49-
class BadToken:
50-
pass
51-
52-
with pytest.raises(TokenSpecificationError):
53-
auth.get_auth(**no_audience_config, token_type=BadToken)
54-
55-
5645
def test__authenticate_user_returns_custom_tokens(
5746
monkeypatch, mock_discovery, token_without_audience, no_audience_config
5847
):
@@ -63,8 +52,8 @@ class CustomToken(IDToken):
6352

6453
token = token_without_audience
6554

66-
authenticate_user = auth.get_auth(**no_audience_config, token_type=CustomToken)
55+
authenticate_user = auth.get_auth(**no_audience_config)
6756

68-
custom_token: CustomToken = authenticate_user(auth_header=f"Bearer {token}")
57+
custom_token = CustomToken(**authenticate_user(auth_header=f"Bearer {token}"))
6958

7059
assert custom_token.custom_field == "OnlySlightlyBent"

0 commit comments

Comments
 (0)