implement proof-of-concept backend authentication
This commit is contained in:
parent
93394769b2
commit
1a0f3726d8
4 changed files with 540 additions and 5 deletions
61
api/main.py
Normal file → Executable file
61
api/main.py
Normal file → Executable file
|
|
@ -1,5 +1,64 @@
|
|||
#!/usr/bin/env python3
|
||||
from typing import Optional
|
||||
from fastapi import FastAPI, Request, Response
|
||||
from fastapi.responses import RedirectResponse
|
||||
from pydantic import BaseModel
|
||||
from contextlib import asynccontextmanager
|
||||
from simple_openid_connect.client import OpenidClient
|
||||
from simple_openid_connect.data import TokenSuccessResponse, IdToken
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
app.extra["oidc_client"] = OpenidClient.from_issuer_url(
|
||||
url="https://id.hamburg.ccc.de/realms/test/",
|
||||
authentication_redirect_uri="http://localhost:8000/auth/login-callback",
|
||||
client_id="dooris",
|
||||
client_secret="dp9HhnvUhAtKm3pRnxfGA7q8Nwrd1td8",
|
||||
)
|
||||
yield
|
||||
|
||||
|
||||
app = FastAPI(lifespan=lifespan)
|
||||
|
||||
|
||||
class UserInfo(BaseModel):
|
||||
name: str
|
||||
|
||||
|
||||
class UserStatus(BaseModel):
|
||||
is_logged_in: bool
|
||||
user_info: Optional[UserInfo]
|
||||
|
||||
|
||||
@app.get("/api/user-info/")
|
||||
async def get_user_info() -> UserStatus:
|
||||
return { "bla": "blub" }
|
||||
|
||||
|
||||
@app.get("/auth/login")
|
||||
async def login_init(req: Request):
|
||||
oidc_client = req.app.extra["oidc_client"] # type: OpenidClient
|
||||
return RedirectResponse(oidc_client.authorization_code_flow.start_authentication())
|
||||
|
||||
|
||||
@app.get("/auth/login-callback")
|
||||
async def login_callback(req: Request, resp: Response):
|
||||
oidc_client = req.app.extra["oidc_client"] # type: OpenidClient
|
||||
auth_result = oidc_client.authorization_code_flow.handle_authentication_result(current_url=req.url)
|
||||
if isinstance(auth_result, TokenSuccessResponse):
|
||||
resp.set_cookie("access_token", auth_result.access_token, httponly=True)
|
||||
resp.set_cookie("id_token", auth_result.id_token)
|
||||
return {"authenticated": True}
|
||||
else:
|
||||
return {"authenticated": False}
|
||||
|
||||
|
||||
def main():
|
||||
print("Hello from api!")
|
||||
import uvicorn
|
||||
config = uvicorn.Config(app, port=8000, log_level="info")
|
||||
server = uvicorn.Server(config)
|
||||
server.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue