fix(oidc): OIDC 端点禁用 DRF 默认 JWT 认证,修复 userinfo 401
DRF CustomJWTAuthentication 会把 Gitea 回传的 RS256 id_token 当 simplejwt token 解析失败返回 401;全部 OIDC 视图 authentication_classes=[],token/userinfo 各自自行校验凭据
This commit is contained in:
1 parent
0b3620223c
commit
39e231bfbf
1 file changed
+19
-5
+19
-5
@@ -44,6 +44,15 @@ from gvsds import secrets as app_secrets
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# === OIDC 视图公共设置 ===
|
||||
# 全部端点不启用 DRF 默认认证(CustomJWTAuthentication 会把 OIDC 签发的 RS256
|
||||
# id_token 当作 simplejwt token 解析失败而 401)。token 端点自行校验 client 凭据,
|
||||
# userinfo 自行校验 Bearer id_token,authorize 自行读取 GERP AccessToken Cookie。
|
||||
OIDC_VIEW_KWARGS = {
|
||||
'authentication_classes': [],
|
||||
'permission_classes': [AllowAny],
|
||||
}
|
||||
|
||||
# === 一次性授权码存储(进程内存) ===
|
||||
_AUTH_CODE_TTL = 600 # code 有效期 10 分钟
|
||||
_AUTH_CODE_STORE = {} # code -> {"user_uuid": str, "nonce": str|None, "exp": float}
|
||||
@@ -205,7 +214,8 @@ def _BuildIdToken(user, gitea, nonce=None):
|
||||
class OIDCDiscoveryView(APIView):
|
||||
"""OIDC Discovery 文档(/.well-known/openid-configuration)。"""
|
||||
|
||||
permission_classes = [AllowAny]
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**{**OIDC_VIEW_KWARGS, **kwargs})
|
||||
|
||||
def get(self, request):
|
||||
base = _Issuer()
|
||||
@@ -230,7 +240,8 @@ class OIDCDiscoveryView(APIView):
|
||||
class OIDCAuthorizeView(APIView):
|
||||
"""授权端点:校验 GERP 会话 → 签发一次性 code → 302 回 Gitea callback。"""
|
||||
|
||||
permission_classes = [AllowAny]
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**{**OIDC_VIEW_KWARGS, **kwargs})
|
||||
|
||||
def get(self, request):
|
||||
client_id = request.query_params.get('client_id', '')
|
||||
@@ -290,7 +301,8 @@ class OIDCAuthorizeView(APIView):
|
||||
class OIDCTokenView(APIView):
|
||||
"""Token 端点:client 凭据认证 + code 换 id_token。"""
|
||||
|
||||
permission_classes = [AllowAny]
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**{**OIDC_VIEW_KWARGS, **kwargs})
|
||||
|
||||
def _CheckClientAuth(self, request):
|
||||
"""校验 client_id + client_secret(Basic 头或 POST body)。"""
|
||||
@@ -349,7 +361,8 @@ class OIDCTokenView(APIView):
|
||||
class OIDCJwksView(APIView):
|
||||
"""JWKS 端点:返回 RSA 公钥供 Gitea 校验 id_token 签名。"""
|
||||
|
||||
permission_classes = [AllowAny]
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**{**OIDC_VIEW_KWARGS, **kwargs})
|
||||
|
||||
def get(self, request):
|
||||
return Response({'keys': [_GetPublicJwk()]})
|
||||
@@ -358,7 +371,8 @@ class OIDCJwksView(APIView):
|
||||
class OIDCUserInfoView(APIView):
|
||||
"""UserInfo 端点(Bearer id_token/access_token)。"""
|
||||
|
||||
permission_classes = [AllowAny]
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**{**OIDC_VIEW_KWARGS, **kwargs})
|
||||
|
||||
def get(self, request):
|
||||
auth = request.META.get('HTTP_AUTHORIZATION', '')
|
||||
|
||||
Reference in new issue
Block a user