惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hacker News: Front Page
A
About on SuperTechFans
腾讯CDC
罗磊的独立博客
博客园 - Franky
Last Week in AI
Last Week in AI
博客园_首页
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Register - Security
The Register - Security
云风的 BLOG
云风的 BLOG
L
LangChain Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
D
Docker
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recorded Future
Recorded Future
Vercel News
Vercel News
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
J
Java Code Geeks
有赞技术团队
有赞技术团队
V
V2EX
IT之家
IT之家
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
雷峰网
雷峰网
Jina AI
Jina AI
B
Blog RSS Feed
H
Help Net Security
N
Netflix TechBlog - Medium
Latest news
Latest news
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - 司徒正美
Y
Y Combinator Blog
人人都是产品经理
人人都是产品经理
Stack Overflow Blog
Stack Overflow Blog
C
Cisco Blogs
Microsoft Security Blog
Microsoft Security Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
大猫的无限游戏
大猫的无限游戏
C
Check Point Blog
P
Proofpoint News Feed
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News and Events Feed by Topic
T
Threatpost

Gary' Blog

Migrate pip to uv - Gary' Blog Terminal autocomplete (only macOS and Linux) How to expand the hard disk capacity of Debian/Ubuntu in ESXi Keycloak configuration problems and solutions Careers and LinkedIn Jobs Page of Fortune 500 American Companies How to connect Windows desktop remotely using RDP and cloudflare ZeroTrust tunnel ESXi 8 issue solved: This PC can’t run Windows 11 How to download and license ESXi 8? Get clicked word using pure Javascript
Authentication FastAPI with Keycloak - Gary' Blog
Gary · 2025-02-04 · via Gary' Blog

First you need to create a realm and client, and get the client id and secret.

Go to Keycloak configuration problems and solutions to see how to setup at Keycloak Admin Panel.

1 Install dependencies

pip install python-jose[cryptography]>=3.3.0
pip install cryptography>=3.4.0
pip install PyJWT==2.10.1

Setup configuration

Add following to your configuration file, like config.py:

from os import getenv

# Keycloak Settings
KEYCLOAK_URL = getenv("KEYCLOAK_URL")
KEYCLOAK_REALM = getenv("KEYCLOAK_REALM")
KEYCLOAK_CLIENT_ID = getenv("KEYCLOAK_CLIENT_ID")
KEYCLOAK_CLIENT_SECRET = getenv("KEYCLOAK_CLIENT_SECRET") 
KEYCLOAK_ALGORITHM = getenv("KEYCLOAK_ALGORITHM", "ES256")

# OpenID Connect endpoints
OIDC_JWKS_URI = f"{KEYCLOAK_URL}/realms/{KEYCLOAK_REALM}/protocol/openid-connect/certs"
OIDC_TOKEN_ENDPOINT = f"{KEYCLOAK_URL}/realms/{KEYCLOAK_REALM}/protocol/openid-connect/token"

2 Add Authentication Service

let’s name it auth_service.py:

from typing import Dict, Any
from jose import jwt, JWTError
from jose.exceptions import JWTClaimsError
from jwt import PyJWKClient
from fastapi import HTTPException, Depends, status
from fastapi.security import OAuth2PasswordBearer

from src.config import (
    KEYCLOAK_ALGORITHM,
    OIDC_JWKS_URI,
    OIDC_TOKEN_ENDPOINT,
    KEYCLOAK_CLIENT_ID,
    KEYCLOAK_CLIENT_SECRET,
)

oauth2_scheme = OAuth2PasswordBearer(tokenUrl=OIDC_TOKEN_ENDPOINT)
jwks_client = PyJWKClient(OIDC_JWKS_URI)

def decode_token(token: str) -> Dict[str, Any]:
    try:
        # Extract the key from the JWKS endpoint
        signing_key = jwks_client.get_signing_key_from_jwt(token).key

        # Decode and verify the token
        payload = jwt.decode(
            token,
            signing_key,
            algorithms=[KEYCLOAK_ALGORITHM],
            audience=KEYCLOAK_CLIENT_ID,
            options={"verify_exp": True}
        )
        return payload
    except JWTClaimsError as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=f"Invalid token claims: {str(e)}"
        )
    except JWTError as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=f"Invalid token: {str(e)}",
            headers={"WWW-Authenticate": "Bearer"},
        )

async def get_current_user(token: str = Depends(oauth2_scheme)):
    if not KEYCLOAK_CLIENT_SECRET:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Keycloak client secret not configured"
        )

    payload = decode_token(token)
    if not payload:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return payload