diff --git a/gvsds/apps/gerp/oidc.py b/gvsds/apps/gerp/oidc.py index b6dc9421..06b85eac 100644 --- a/gvsds/apps/gerp/oidc.py +++ b/gvsds/apps/gerp/oidc.py @@ -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', '')