Skip to content

Commit 630978c

Browse files
committed
improve: select grant flows
1 parent f204ad8 commit 630978c

File tree

13 files changed

+2101
-74
lines changed

13 files changed

+2101
-74
lines changed

README.md

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,33 +56,28 @@ fastapi-oidc + keycloak.
5656
### Standard usage
5757

5858
```python3
59-
from typing import Optional
60-
6159
from fastapi import Depends
6260
from fastapi import FastAPI
6361
from fastapi import Security
6462
from fastapi import status
6563

6664
from fastapi_oidc import Auth
65+
from fastapi_oidc import GrantType
6766
from fastapi_oidc import KeycloakIDToken
6867

6968
auth = Auth(
7069
openid_connect_url="http://localhost:8080/auth/realms/my-realm/.well-known/openid-configuration",
7170
issuer="http://localhost:8080/auth/realms/my-realm", # optional, verification only
7271
client_id="my-client", # optional, verification only
7372
scopes=["email"], # optional, verification only
73+
grant_types=[GrantType.IMPLICIT], # optional, docs only
7474
idtoken_model=KeycloakIDToken, # optional, verification only
7575
)
7676

7777
app = FastAPI(
7878
title="Example",
7979
version="dev",
80-
dependencies=[Depends(auth.implicit_scheme)],
81-
# multiple available schemes:
82-
# - oidc_scheme (displays all schemes supported by the auth server in docs)
83-
# - password_scheme
84-
# - implicit_scheme
85-
# - authcode_scheme
80+
dependencies=[Depends(auth)],
8681
)
8782

8883
@app.get("/protected")

docs/index.rst

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Easily used with authenticators such as:
1212
- `Okta <https://www.okta.com/products/authentication/>`_
1313

1414

15-
FastAPI's generated interactive documentation supports the grant flows
15+
FastAPI's generated interactive documentation supports the grant types
1616
``authorization_code``, ``implicit``, ``password`` and ``client_credentials``.
1717

1818
.. toctree::
@@ -46,33 +46,28 @@ Basic configuration for verifying OIDC tokens.
4646

4747
.. code-block:: python3
4848
49-
from typing import Optional
50-
5149
from fastapi import Depends
5250
from fastapi import FastAPI
5351
from fastapi import Security
5452
from fastapi import status
5553
5654
from fastapi_oidc import Auth
55+
from fastapi_oidc import GrantType
5756
from fastapi_oidc import KeycloakIDToken
5857
5958
auth = Auth(
6059
openid_connect_url="http://localhost:8080/auth/realms/my-realm/.well-known/openid-configuration",
6160
issuer="http://localhost:8080/auth/realms/my-realm", # optional, verification only
6261
client_id="my-client", # optional, verification only
6362
scopes=["email"], # optional, verification only
63+
grant_types=[GrantType.IMPLICIT], # optional, docs only
6464
idtoken_model=KeycloakIDToken, # optional, verification only
6565
)
6666
6767
app = FastAPI(
6868
title="Example",
6969
version="dev",
70-
dependencies=[Depends(auth.implicit_scheme)],
71-
# multiple available schemes:
72-
# - oidc_scheme (displays all schemes supported by the auth server in docs)
73-
# - password_scheme
74-
# - implicit_scheme
75-
# - authcode_scheme
70+
dependencies=[Depends(auth)],
7671
)
7772
7873
@app.get("/protected")
@@ -85,11 +80,16 @@ API Reference
8580

8681
Auth
8782
----
88-
8983
.. automodule:: fastapi_oidc.auth
9084
:members:
9185

92-
Types
93-
------------
94-
.. automodule:: fastapi_oidc.types
86+
Grant Types
87+
-----------
88+
.. automodule:: fastapi_oidc.grant_types
89+
:members:
90+
:undoc-members:
91+
92+
IDToken Types
93+
-------------
94+
.. automodule:: fastapi_oidc.idtoken_types
9595
:members:

example/app/__init__.py

Whitespace-only changes.

example/app/main.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from typing import Optional
2+
3+
import uvicorn
4+
from fastapi import Depends
5+
from fastapi import FastAPI
6+
from fastapi import Security
7+
from fastapi import status
8+
from fastapi.middleware.cors import CORSMiddleware
9+
from starlette.responses import RedirectResponse
10+
11+
from fastapi_oidc import Auth
12+
from fastapi_oidc import KeycloakIDToken
13+
14+
auth = Auth(
15+
openid_connect_url="http://localhost:8080/auth/realms/my-realm/.well-known/openid-configuration",
16+
issuer="http://localhost:8080/auth/realms/my-realm", # optional, verification only
17+
client_id="my-client", # optional, verification only
18+
scopes=["email"], # optional, verification only
19+
idtoken_model=KeycloakIDToken, # optional, verification only
20+
)
21+
22+
app = FastAPI(
23+
title="Example",
24+
version="dev",
25+
dependencies=[Depends(auth)],
26+
)
27+
28+
# CORS errors instead of seeing internal exceptions
29+
# https://stackoverflow.com/questions/63606055/why-do-i-get-cors-error-reason-cors-request-did-not-succeed
30+
cors = CORSMiddleware(
31+
app=app,
32+
allow_origins=["*"],
33+
allow_credentials=True,
34+
allow_methods=["*"],
35+
allow_headers=["*"],
36+
)
37+
38+
39+
@app.get("/", status_code=status.HTTP_303_SEE_OTHER)
40+
def redirect_to_docs():
41+
return RedirectResponse(url="/docs")
42+
43+
44+
@app.get("/protected")
45+
def protected(id_token: KeycloakIDToken = Security(auth.required)):
46+
print(id_token)
47+
return dict(message=f"You are {id_token.email}")
48+
49+
50+
@app.get("/mixed")
51+
def mixed(id_token: Optional[KeycloakIDToken] = Security(auth.optional)):
52+
if id_token is None:
53+
return dict(message="Welcome guest user!")
54+
else:
55+
return dict(message=f"Welcome {id_token.email}!")
56+
57+
58+
if __name__ == "__main__":
59+
uvicorn.run(
60+
"example.main:cors", host="0.0.0.0", port=8000, loop="asyncio", reload=True
61+
)

example/docker-compose.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
version: '3'
2+
3+
services:
4+
5+
# test-fastapi-keycloak:
6+
# build:
7+
# context: .
8+
# dockerfile: Dockerfile
9+
# restart: always
10+
# depends_on:
11+
# - keycloak
12+
# # keycloak:
13+
# # condition: service_healthy
14+
# network_mode: host
15+
16+
keycloak:
17+
image: jboss/keycloak:15.0.2
18+
volumes:
19+
- ./my-realm-export.json:/tmp/my-realm-export.json
20+
environment:
21+
- DB_VENDOR=POSTGRES
22+
- DB_ADDR=keycloak-postgres
23+
- DB_DATABASE=keycloak
24+
- DB_USER=keycloak
25+
- DB_SCHEMA=public
26+
- DB_PASSWORD=password
27+
- KEYCLOAK_USER=admin
28+
- KEYCLOAK_PASSWORD=admin
29+
- KEYCLOAK_IMPORT=/tmp/my-realm-export.json
30+
ports:
31+
- 8080:8080
32+
depends_on:
33+
- keycloak-postgres
34+
# healthcheck:
35+
# test: ["CMD", "curl", "-f", "http://keycloak:8080"]
36+
# interval: 10s
37+
# timeout: 10s
38+
# retries: 2
39+
40+
keycloak-postgres:
41+
image: postgres:13.4-alpine3.14
42+
volumes:
43+
- ./data/keycloak-postgres:/var/lib/postgresql/data/
44+
environment:
45+
- POSTGRES_USER=keycloak
46+
- POSTGRES_PASSWORD=password
47+
- POSTGRES_DB=keycloak

0 commit comments

Comments
 (0)