skyplatform-iam 1.0.1__py3-none-any.whl → 1.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- skyplatform_iam/__init__.py +77 -17
- skyplatform_iam/api.py +366 -0
- skyplatform_iam/config.py +173 -18
- skyplatform_iam/connect_agenterra_iam.py +291 -12
- skyplatform_iam/global_manager.py +272 -0
- skyplatform_iam/middleware.py +363 -24
- skyplatform_iam-1.0.5.dist-info/METADATA +461 -0
- skyplatform_iam-1.0.5.dist-info/RECORD +10 -0
- skyplatform_iam/auth_middleware.py +0 -201
- skyplatform_iam-1.0.1.dist-info/METADATA +0 -262
- skyplatform_iam-1.0.1.dist-info/RECORD +0 -9
- {skyplatform_iam-1.0.1.dist-info → skyplatform_iam-1.0.5.dist-info}/WHEEL +0 -0
skyplatform_iam/middleware.py
CHANGED
|
@@ -3,16 +3,20 @@ SkyPlatform IAM SDK 中间件模块
|
|
|
3
3
|
"""
|
|
4
4
|
import logging
|
|
5
5
|
from typing import Optional, Callable, Dict, Any
|
|
6
|
-
from fastapi import Request, Response, HTTPException
|
|
6
|
+
from fastapi import Request, Response, HTTPException, status
|
|
7
7
|
from fastapi.responses import JSONResponse
|
|
8
|
+
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
8
9
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
10
|
+
import jwt
|
|
9
11
|
|
|
10
12
|
from .config import AuthConfig
|
|
11
13
|
from .connect_agenterra_iam import ConnectAgenterraIam
|
|
14
|
+
from .global_manager import get_global_manager
|
|
12
15
|
from .exceptions import (
|
|
13
16
|
AuthenticationError,
|
|
14
17
|
AuthorizationError,
|
|
15
|
-
ConfigurationError
|
|
18
|
+
ConfigurationError,
|
|
19
|
+
IAMServiceError
|
|
16
20
|
)
|
|
17
21
|
|
|
18
22
|
logger = logging.getLogger(__name__)
|
|
@@ -22,38 +26,91 @@ class AuthMiddleware(BaseHTTPMiddleware):
|
|
|
22
26
|
"""
|
|
23
27
|
认证中间件
|
|
24
28
|
自动拦截请求进行Token验证和权限检查
|
|
29
|
+
支持全局实例共享和延迟初始化
|
|
25
30
|
"""
|
|
26
31
|
|
|
27
32
|
def __init__(
|
|
28
33
|
self,
|
|
29
34
|
app,
|
|
30
|
-
config: AuthConfig,
|
|
31
|
-
skip_validation: Optional[Callable[[Request], bool]] = None
|
|
35
|
+
config: Optional[AuthConfig] = None,
|
|
36
|
+
skip_validation: Optional[Callable[[Request], bool]] = None,
|
|
37
|
+
use_global_manager: bool = True
|
|
32
38
|
):
|
|
33
39
|
"""
|
|
34
40
|
初始化认证中间件
|
|
35
41
|
|
|
36
42
|
Args:
|
|
37
43
|
app: FastAPI应用实例
|
|
38
|
-
config:
|
|
44
|
+
config: 认证配置,如果为None且use_global_manager=True,则从全局管理器获取
|
|
39
45
|
skip_validation: 自定义跳过验证的函数
|
|
46
|
+
use_global_manager: 是否使用全局管理器(推荐)
|
|
40
47
|
"""
|
|
41
48
|
super().__init__(app)
|
|
42
|
-
self.
|
|
43
|
-
self.iam_client = ConnectAgenterraIam()
|
|
49
|
+
self.use_global_manager = use_global_manager
|
|
44
50
|
self.skip_validation = skip_validation
|
|
51
|
+
|
|
52
|
+
if use_global_manager:
|
|
53
|
+
# 使用全局管理器(延迟初始化)
|
|
54
|
+
self.config = None
|
|
55
|
+
self.iam_client = None
|
|
56
|
+
logger.info("AuthMiddleware使用全局管理器模式")
|
|
57
|
+
else:
|
|
58
|
+
# 传统模式(向后兼容)
|
|
59
|
+
if config is None:
|
|
60
|
+
raise ConfigurationError("在非全局管理器模式下,config参数不能为None")
|
|
61
|
+
self.config = config
|
|
62
|
+
self.iam_client = ConnectAgenterraIam(config=config)
|
|
63
|
+
|
|
64
|
+
# 验证配置
|
|
65
|
+
try:
|
|
66
|
+
self.config.validate_config()
|
|
67
|
+
except ValueError as e:
|
|
68
|
+
raise ConfigurationError(str(e))
|
|
69
|
+
logger.info("AuthMiddleware使用传统模式")
|
|
70
|
+
|
|
71
|
+
def _get_config_and_client(self):
|
|
72
|
+
"""获取配置和客户端实例"""
|
|
73
|
+
if self.use_global_manager:
|
|
74
|
+
try:
|
|
75
|
+
manager = get_global_manager()
|
|
76
|
+
if not manager.is_initialized():
|
|
77
|
+
raise IAMServiceError("SkyPlatform IAM SDK未初始化,请先调用init_skyplatform_iam()")
|
|
78
|
+
return manager.get_config(), manager.get_client()
|
|
79
|
+
except Exception as e:
|
|
80
|
+
logger.error(f"从全局管理器获取配置和客户端失败: {str(e)}")
|
|
81
|
+
raise IAMServiceError(f"获取IAM配置失败: {str(e)}")
|
|
82
|
+
else:
|
|
83
|
+
return self.config, self.iam_client
|
|
45
84
|
|
|
46
|
-
|
|
85
|
+
def is_path_whitelisted(self, path: str) -> bool:
|
|
86
|
+
"""
|
|
87
|
+
检查路径是否在本地白名单中
|
|
88
|
+
"""
|
|
47
89
|
try:
|
|
48
|
-
self.
|
|
49
|
-
|
|
50
|
-
|
|
90
|
+
config, _ = self._get_config_and_client()
|
|
91
|
+
return config.is_path_whitelisted(path)
|
|
92
|
+
except Exception as e:
|
|
93
|
+
logger.error(f"检查白名单路径失败: {str(e)}")
|
|
94
|
+
return False
|
|
51
95
|
|
|
52
96
|
async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
|
53
97
|
"""
|
|
54
98
|
中间件主要处理逻辑
|
|
55
99
|
"""
|
|
56
100
|
try:
|
|
101
|
+
# 获取请求路径
|
|
102
|
+
api_path = request.url.path
|
|
103
|
+
|
|
104
|
+
# 首先检查路径是否在本地白名单中
|
|
105
|
+
if self.is_path_whitelisted(api_path):
|
|
106
|
+
logger.info(f"路径 {api_path} 在本地白名单中,跳过认证直接允许访问")
|
|
107
|
+
# 设置白名单标识
|
|
108
|
+
request.state.user = None
|
|
109
|
+
request.state.authenticated = False
|
|
110
|
+
request.state.is_whitelist = True
|
|
111
|
+
# 直接调用下一个处理器
|
|
112
|
+
response = await call_next(request)
|
|
113
|
+
return response
|
|
57
114
|
|
|
58
115
|
# 提取Token(可能为空,白名单接口不需要token)
|
|
59
116
|
token = self._extract_token(request)
|
|
@@ -84,7 +141,6 @@ class AuthMiddleware(BaseHTTPMiddleware):
|
|
|
84
141
|
return response
|
|
85
142
|
|
|
86
143
|
except HTTPException as e:
|
|
87
|
-
# FastAPI HTTPException直接返回
|
|
88
144
|
return self._create_error_response(
|
|
89
145
|
status_code=e.status_code,
|
|
90
146
|
message=str(e.detail),
|
|
@@ -117,23 +173,31 @@ class AuthMiddleware(BaseHTTPMiddleware):
|
|
|
117
173
|
"""
|
|
118
174
|
从请求中提取Token
|
|
119
175
|
"""
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
176
|
+
try:
|
|
177
|
+
config, _ = self._get_config_and_client()
|
|
178
|
+
|
|
179
|
+
# 从Authorization头提取
|
|
180
|
+
auth_header = request.headers.get(config.token_header)
|
|
181
|
+
if auth_header and auth_header.startswith(config.token_prefix):
|
|
182
|
+
return auth_header[len(config.token_prefix):].strip()
|
|
124
183
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
184
|
+
# 从查询参数提取(备选方案)
|
|
185
|
+
token = request.query_params.get("token")
|
|
186
|
+
if token:
|
|
187
|
+
return token
|
|
129
188
|
|
|
130
|
-
|
|
189
|
+
return None
|
|
190
|
+
except Exception as e:
|
|
191
|
+
logger.error(f"提取Token失败: {str(e)}")
|
|
192
|
+
return None
|
|
131
193
|
|
|
132
194
|
async def _verify_token_and_permission(self, request: Request, token: Optional[str]) -> Optional[Dict[str, Any]]:
|
|
133
195
|
"""
|
|
134
196
|
验证Token和权限
|
|
135
197
|
"""
|
|
136
198
|
try:
|
|
199
|
+
config, iam_client = self._get_config_and_client()
|
|
200
|
+
|
|
137
201
|
# 获取请求信息
|
|
138
202
|
api_path = request.url.path
|
|
139
203
|
method = request.method
|
|
@@ -143,7 +207,7 @@ class AuthMiddleware(BaseHTTPMiddleware):
|
|
|
143
207
|
server_sk = request.headers.get("SERVER-SK", "")
|
|
144
208
|
|
|
145
209
|
# 调用IAM验证接口(即使token为空也要调用,因为可能是白名单接口)
|
|
146
|
-
user_info =
|
|
210
|
+
user_info = iam_client.verify_token(
|
|
147
211
|
token=token or "", # 如果token为None,传递空字符串
|
|
148
212
|
api=api_path,
|
|
149
213
|
method=method,
|
|
@@ -158,8 +222,12 @@ class AuthMiddleware(BaseHTTPMiddleware):
|
|
|
158
222
|
raise
|
|
159
223
|
except Exception as e:
|
|
160
224
|
logger.error(f"Token验证异常: {str(e)}")
|
|
161
|
-
|
|
162
|
-
|
|
225
|
+
try:
|
|
226
|
+
config, _ = self._get_config_and_client()
|
|
227
|
+
if config.enable_debug:
|
|
228
|
+
logger.exception("详细异常信息:")
|
|
229
|
+
except:
|
|
230
|
+
pass
|
|
163
231
|
return None
|
|
164
232
|
|
|
165
233
|
def _create_error_response(
|
|
@@ -184,3 +252,274 @@ class AuthMiddleware(BaseHTTPMiddleware):
|
|
|
184
252
|
status_code=status_code,
|
|
185
253
|
content=error_data
|
|
186
254
|
)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class AuthService:
|
|
258
|
+
"""
|
|
259
|
+
认证服务类
|
|
260
|
+
提供依赖注入式的认证功能
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
def __init__(self, auth_config: AuthConfig):
|
|
264
|
+
if auth_config is None:
|
|
265
|
+
raise ValueError("auth_config参数不能为None,必须传入AuthConfig配置对象")
|
|
266
|
+
self.security = HTTPBearer(auto_error=False)
|
|
267
|
+
self.iam_client = ConnectAgenterraIam(config=auth_config)
|
|
268
|
+
self.auth_config = auth_config
|
|
269
|
+
|
|
270
|
+
def is_path_whitelisted(self, path: str) -> bool:
|
|
271
|
+
"""
|
|
272
|
+
检查路径是否在白名单中
|
|
273
|
+
"""
|
|
274
|
+
if not self.auth_config:
|
|
275
|
+
return False
|
|
276
|
+
return self.auth_config.is_path_whitelisted(path)
|
|
277
|
+
|
|
278
|
+
async def verify_token(self, request: Request):
|
|
279
|
+
"""验证token和权限"""
|
|
280
|
+
# 通过token, server_ak, server_sk判断是否有权限
|
|
281
|
+
api_path = request.url.path
|
|
282
|
+
|
|
283
|
+
# 首先检查路径是否在白名单中
|
|
284
|
+
if self.is_path_whitelisted(api_path):
|
|
285
|
+
logger.info(f"路径 {api_path} 在白名单中,跳过IAM鉴权")
|
|
286
|
+
return True
|
|
287
|
+
|
|
288
|
+
credentials: HTTPAuthorizationCredentials = await self.security(request)
|
|
289
|
+
method = request.method
|
|
290
|
+
|
|
291
|
+
server_ak = request.headers.get("SERVER-AK", "")
|
|
292
|
+
server_sk = request.headers.get("SERVER-SK", "")
|
|
293
|
+
|
|
294
|
+
token = ""
|
|
295
|
+
if credentials is not None:
|
|
296
|
+
token = credentials.credentials
|
|
297
|
+
user_info_by_iam = self.iam_client.verify_token(token, api_path, method, server_ak, server_sk)
|
|
298
|
+
if user_info_by_iam:
|
|
299
|
+
return True
|
|
300
|
+
return False
|
|
301
|
+
|
|
302
|
+
async def get_current_user(self, request: Request) -> Optional[Dict]:
|
|
303
|
+
"""获取当前用户信息"""
|
|
304
|
+
try:
|
|
305
|
+
# 直接调用verify_token方法进行token验证
|
|
306
|
+
if not await self.verify_token(request):
|
|
307
|
+
return None
|
|
308
|
+
|
|
309
|
+
# 获取token用于后续用户信息获取
|
|
310
|
+
credentials: HTTPAuthorizationCredentials = await self.security(request)
|
|
311
|
+
if not credentials:
|
|
312
|
+
return None
|
|
313
|
+
|
|
314
|
+
token = credentials.credentials
|
|
315
|
+
|
|
316
|
+
# 直接解析JWT token获取payload
|
|
317
|
+
payload = self.decode_jwt_token(token)
|
|
318
|
+
if not payload:
|
|
319
|
+
logger.error("JWT token解析失败")
|
|
320
|
+
return None
|
|
321
|
+
|
|
322
|
+
# 从payload中提取用户信息
|
|
323
|
+
iam_user_id = payload.get("sub") # JWT标准中用户ID存储在sub字段
|
|
324
|
+
username = None
|
|
325
|
+
|
|
326
|
+
# 解析新的凭证信息结构
|
|
327
|
+
all_credentials = payload.get("all_credentials", [])
|
|
328
|
+
total_credentials = payload.get("total_credentials", 0)
|
|
329
|
+
|
|
330
|
+
# 从all_credentials中提取username(向后兼容)
|
|
331
|
+
for cred in all_credentials:
|
|
332
|
+
if cred.get("type") == "username":
|
|
333
|
+
username = cred.get("value")
|
|
334
|
+
break
|
|
335
|
+
|
|
336
|
+
# 向后兼容性:如果没有all_credentials,尝试从payload的其他字段构建
|
|
337
|
+
if not all_credentials:
|
|
338
|
+
credentials_list = []
|
|
339
|
+
# 检查payload中是否有直接的username字段
|
|
340
|
+
if payload.get("username"):
|
|
341
|
+
username = payload.get("username")
|
|
342
|
+
credentials_list.append({"type": "username", "value": username})
|
|
343
|
+
if payload.get("email"):
|
|
344
|
+
credentials_list.append({"type": "email", "value": payload.get("email")})
|
|
345
|
+
if payload.get("phone"):
|
|
346
|
+
credentials_list.append({"type": "phone", "value": payload.get("phone")})
|
|
347
|
+
all_credentials = credentials_list
|
|
348
|
+
total_credentials = len(credentials_list)
|
|
349
|
+
|
|
350
|
+
if not username:
|
|
351
|
+
return None
|
|
352
|
+
|
|
353
|
+
# 构建用户信息字典
|
|
354
|
+
user_info = {
|
|
355
|
+
"id": iam_user_id,
|
|
356
|
+
"username": username,
|
|
357
|
+
"all_credentials": all_credentials,
|
|
358
|
+
"total_credentials": total_credentials,
|
|
359
|
+
"microservice": payload.get("microservice") # 添加微服务信息
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
# 向后兼容:添加传统字段映射
|
|
363
|
+
for cred in all_credentials:
|
|
364
|
+
if cred.get("type") == "email":
|
|
365
|
+
user_info["email"] = cred.get("value")
|
|
366
|
+
elif cred.get("type") == "phone":
|
|
367
|
+
user_info["phone"] = cred.get("value")
|
|
368
|
+
elif cred.get("type") == "username" and not user_info.get("username"):
|
|
369
|
+
user_info["username"] = cred.get("value")
|
|
370
|
+
|
|
371
|
+
# 统计凭证类型分布
|
|
372
|
+
cred_types = [cred.get("type") for cred in all_credentials]
|
|
373
|
+
cred_type_count = {cred_type: cred_types.count(cred_type) for cred_type in set(cred_types)}
|
|
374
|
+
|
|
375
|
+
logger.info(
|
|
376
|
+
f"用户认证成功: user_id={iam_user_id}, username={username}, 凭证数量={total_credentials}, 凭证类型分布={cred_type_count}")
|
|
377
|
+
logger.debug(f"JWT payload: {payload}")
|
|
378
|
+
|
|
379
|
+
# 将用户信息添加到请求状态中
|
|
380
|
+
request.state.user = user_info
|
|
381
|
+
return user_info
|
|
382
|
+
|
|
383
|
+
except HTTPException as e:
|
|
384
|
+
logger.error(f"获取当前用户信息失败: {str(e)}")
|
|
385
|
+
# 重新抛出HTTP异常(403权限不足)
|
|
386
|
+
return None
|
|
387
|
+
except Exception as e:
|
|
388
|
+
logger.error(f"获取当前用户信息失败: {str(e)}")
|
|
389
|
+
return None
|
|
390
|
+
|
|
391
|
+
async def require_auth(self, request: Request) -> Dict:
|
|
392
|
+
"""要求用户必须登录"""
|
|
393
|
+
try:
|
|
394
|
+
user_info = await self.get_current_user(request)
|
|
395
|
+
if not user_info:
|
|
396
|
+
raise HTTPException(
|
|
397
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
398
|
+
detail="需要登录认证",
|
|
399
|
+
headers={"WWW-Authenticate": "Bearer"},
|
|
400
|
+
)
|
|
401
|
+
return user_info
|
|
402
|
+
except HTTPException:
|
|
403
|
+
# 重新抛出HTTP异常(可能是403权限不足或401未认证)
|
|
404
|
+
raise
|
|
405
|
+
|
|
406
|
+
async def optional_auth(self, request: Request) -> Optional[Dict]:
|
|
407
|
+
"""可选的用户认证(不强制要求登录)"""
|
|
408
|
+
try:
|
|
409
|
+
return await self.get_current_user(request)
|
|
410
|
+
except HTTPException:
|
|
411
|
+
# 对于可选认证,如果是403权限不足,仍然抛出异常
|
|
412
|
+
# 如果是401未认证,返回None
|
|
413
|
+
raise
|
|
414
|
+
|
|
415
|
+
def decode_jwt_token(self, token: str) -> Optional[Dict]:
|
|
416
|
+
"""直接解析JWT token获取payload"""
|
|
417
|
+
try:
|
|
418
|
+
# 不验证签名,只解析payload(因为token已经通过verify_token验证过)
|
|
419
|
+
decoded_payload = jwt.decode(token, options={"verify_signature": False})
|
|
420
|
+
logger.debug(f"JWT token解析成功: {decoded_payload}")
|
|
421
|
+
return decoded_payload
|
|
422
|
+
except jwt.InvalidTokenError as e:
|
|
423
|
+
logger.error(f"JWT token解析失败: {str(e)}")
|
|
424
|
+
return None
|
|
425
|
+
except Exception as e:
|
|
426
|
+
logger.error(f"JWT token解析异常: {str(e)}")
|
|
427
|
+
return None
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
# 全局认证服务实例(延迟初始化)
|
|
431
|
+
auth_service = None
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
def setup_auth_middleware(auth_config: AuthConfig) -> None:
|
|
435
|
+
"""
|
|
436
|
+
设置认证中间件配置(向后兼容)
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
auth_config: 认证配置实例,包含白名单路径等配置
|
|
440
|
+
|
|
441
|
+
Deprecated:
|
|
442
|
+
请使用 init_skyplatform_iam() 替代
|
|
443
|
+
"""
|
|
444
|
+
global auth_service
|
|
445
|
+
auth_service = AuthService(auth_config)
|
|
446
|
+
logger.warning("setup_auth_middleware()已废弃,请使用init_skyplatform_iam()替代")
|
|
447
|
+
logger.info(f"认证中间件已配置,白名单路径数量: {len(auth_config.get_whitelist_paths())}")
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def create_auth_middleware(
|
|
451
|
+
app,
|
|
452
|
+
config: Optional[AuthConfig] = None,
|
|
453
|
+
use_global_manager: bool = True
|
|
454
|
+
) -> AuthMiddleware:
|
|
455
|
+
"""
|
|
456
|
+
创建认证中间件实例
|
|
457
|
+
|
|
458
|
+
Args:
|
|
459
|
+
app: FastAPI应用实例
|
|
460
|
+
config: 认证配置,如果为None且use_global_manager=True,则从全局管理器获取
|
|
461
|
+
use_global_manager: 是否使用全局管理器(推荐)
|
|
462
|
+
|
|
463
|
+
Returns:
|
|
464
|
+
AuthMiddleware: 认证中间件实例
|
|
465
|
+
|
|
466
|
+
Example:
|
|
467
|
+
# 使用全局管理器(推荐)
|
|
468
|
+
middleware = create_auth_middleware(app)
|
|
469
|
+
|
|
470
|
+
# 传统模式(向后兼容)
|
|
471
|
+
middleware = create_auth_middleware(app, config, use_global_manager=False)
|
|
472
|
+
"""
|
|
473
|
+
return AuthMiddleware(app, config, use_global_manager=use_global_manager)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
# 便捷的依赖函数
|
|
477
|
+
async def get_current_user(request: Request) -> Dict:
|
|
478
|
+
"""
|
|
479
|
+
获取当前用户的依赖函数
|
|
480
|
+
优先使用全局管理器,向后兼容传统模式
|
|
481
|
+
"""
|
|
482
|
+
try:
|
|
483
|
+
# 尝试使用全局管理器
|
|
484
|
+
manager = get_global_manager()
|
|
485
|
+
if manager.is_initialized():
|
|
486
|
+
user_info = await manager.get_current_user_info(request)
|
|
487
|
+
if user_info is None:
|
|
488
|
+
raise HTTPException(
|
|
489
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
490
|
+
detail="需要登录认证",
|
|
491
|
+
headers={"WWW-Authenticate": "Bearer"},
|
|
492
|
+
)
|
|
493
|
+
return user_info
|
|
494
|
+
except IAMServiceError:
|
|
495
|
+
pass # 全局管理器未初始化,尝试传统模式
|
|
496
|
+
|
|
497
|
+
# 传统模式(向后兼容)
|
|
498
|
+
if auth_service is None:
|
|
499
|
+
raise HTTPException(
|
|
500
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
501
|
+
detail="认证服务未初始化,请先调用init_skyplatform_iam()或setup_auth_middleware()函数进行配置"
|
|
502
|
+
)
|
|
503
|
+
return await auth_service.require_auth(request)
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
async def get_optional_user(request: Request) -> Optional[Dict]:
|
|
507
|
+
"""
|
|
508
|
+
获取可选当前用户的依赖函数
|
|
509
|
+
优先使用全局管理器,向后兼容传统模式
|
|
510
|
+
"""
|
|
511
|
+
try:
|
|
512
|
+
# 尝试使用全局管理器
|
|
513
|
+
manager = get_global_manager()
|
|
514
|
+
if manager.is_initialized():
|
|
515
|
+
return await manager.get_current_user_info(request)
|
|
516
|
+
except IAMServiceError:
|
|
517
|
+
pass # 全局管理器未初始化,尝试传统模式
|
|
518
|
+
|
|
519
|
+
# 传统模式(向后兼容)
|
|
520
|
+
if auth_service is None:
|
|
521
|
+
raise HTTPException(
|
|
522
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
523
|
+
detail="认证服务未初始化,请先调用init_skyplatform_iam()或setup_auth_middleware()函数进行配置"
|
|
524
|
+
)
|
|
525
|
+
return await auth_service.optional_auth(request)
|