skyplatform-iam 1.0.5__py3-none-any.whl → 1.2.0__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.
@@ -11,12 +11,10 @@ import jwt
11
11
 
12
12
  from .config import AuthConfig
13
13
  from .connect_agenterra_iam import ConnectAgenterraIam
14
- from .global_manager import get_global_manager
15
14
  from .exceptions import (
16
15
  AuthenticationError,
17
16
  AuthorizationError,
18
- ConfigurationError,
19
- IAMServiceError
17
+ ConfigurationError
20
18
  )
21
19
 
22
20
  logger = logging.getLogger(__name__)
@@ -26,72 +24,40 @@ class AuthMiddleware(BaseHTTPMiddleware):
26
24
  """
27
25
  认证中间件
28
26
  自动拦截请求进行Token验证和权限检查
29
- 支持全局实例共享和延迟初始化
30
27
  """
31
28
 
32
29
  def __init__(
33
30
  self,
34
31
  app,
35
- config: Optional[AuthConfig] = None,
36
- skip_validation: Optional[Callable[[Request], bool]] = None,
37
- use_global_manager: bool = True
32
+ config: AuthConfig,
33
+ skip_validation: Optional[Callable[[Request], bool]] = None
38
34
  ):
39
35
  """
40
36
  初始化认证中间件
41
37
 
42
38
  Args:
43
39
  app: FastAPI应用实例
44
- config: 认证配置,如果为None且use_global_manager=True,则从全局管理器获取
40
+ config: 认证配置
45
41
  skip_validation: 自定义跳过验证的函数
46
- use_global_manager: 是否使用全局管理器(推荐)
47
42
  """
48
43
  super().__init__(app)
49
- self.use_global_manager = use_global_manager
44
+ self.config = config
45
+ self.iam_client = ConnectAgenterraIam(config=config)
50
46
  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
47
+
48
+ # 验证配置
49
+ try:
50
+ self.config.validate_config()
51
+ except ValueError as e:
52
+ raise ConfigurationError(str(e))
84
53
 
85
54
  def is_path_whitelisted(self, path: str) -> bool:
86
55
  """
87
56
  检查路径是否在本地白名单中
88
57
  """
89
- try:
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)}")
58
+ if not self.config:
94
59
  return False
60
+ return self.config.is_path_whitelisted(path)
95
61
 
96
62
  async def dispatch(self, request: Request, call_next: Callable) -> Response:
97
63
  """
@@ -100,7 +66,14 @@ class AuthMiddleware(BaseHTTPMiddleware):
100
66
  try:
101
67
  # 获取请求路径
102
68
  api_path = request.url.path
103
-
69
+ method = request.method
70
+
71
+ # 检查是否为机机接口鉴权 来自其他服务
72
+ server_ak = request.headers.get('SERVER-AK')
73
+ server_sk = request.headers.get('SERVER-SK')
74
+ # 检查是否为人机接口鉴权 来自前端
75
+ # token = request.headers.get('Authorization')
76
+
104
77
  # 首先检查路径是否在本地白名单中
105
78
  if self.is_path_whitelisted(api_path):
106
79
  logger.info(f"路径 {api_path} 在本地白名单中,跳过认证直接允许访问")
@@ -114,6 +87,7 @@ class AuthMiddleware(BaseHTTPMiddleware):
114
87
 
115
88
  # 提取Token(可能为空,白名单接口不需要token)
116
89
  token = self._extract_token(request)
90
+ machine_token = self._extract_machine_token(request)
117
91
 
118
92
  # 验证Token和权限(即使token为空也要调用IAM验证,因为可能是白名单接口)
119
93
  user_info = await self._verify_token_and_permission(request, token)
@@ -131,6 +105,11 @@ class AuthMiddleware(BaseHTTPMiddleware):
131
105
  request.state.authenticated = False
132
106
  request.state.is_whitelist = True
133
107
  else:
108
+ if machine_token:
109
+ payload = jwt.decode(machine_token, algorithms=["HS256"], options={"verify_signature": False})
110
+ user_id = payload.get("sub", None)
111
+ request.state.user_id = user_id
112
+
134
113
  # 正常认证接口,设置用户信息
135
114
  request.state.user = user_info
136
115
  request.state.authenticated = True
@@ -173,31 +152,37 @@ class AuthMiddleware(BaseHTTPMiddleware):
173
152
  """
174
153
  从请求中提取Token
175
154
  """
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()
183
-
184
- # 从查询参数提取(备选方案)
185
- token = request.query_params.get("token")
186
- if token:
187
- return token
155
+ # 从Authorization头提取
156
+ auth_header = request.headers.get(self.config.token_header)
157
+ if auth_header and auth_header.startswith(self.config.token_prefix):
158
+ print("has auth_header: ", auth_header)
159
+ return auth_header[len(self.config.token_prefix):].strip()
188
160
 
189
- return None
190
- except Exception as e:
191
- logger.error(f"提取Token失败: {str(e)}")
192
- return None
161
+ # 从查询参数提取(备选方案)
162
+ token = request.query_params.get("token")
163
+ if token:
164
+ print("has token: ", token)
165
+ return token
166
+
167
+ return None
168
+
169
+ def _extract_machine_token(self, request: Request) -> Optional[str]:
170
+ """
171
+ 从请求中提取Token
172
+ """
173
+ # 从Authorization头提取
174
+ machine_token = request.headers.get("MACHINE-TOKEN")
175
+ if machine_token:
176
+ print("has MACHINE-TOKEN': ", machine_token)
177
+ return machine_token
178
+
179
+ return None
193
180
 
194
181
  async def _verify_token_and_permission(self, request: Request, token: Optional[str]) -> Optional[Dict[str, Any]]:
195
182
  """
196
183
  验证Token和权限
197
184
  """
198
185
  try:
199
- config, iam_client = self._get_config_and_client()
200
-
201
186
  # 获取请求信息
202
187
  api_path = request.url.path
203
188
  method = request.method
@@ -205,14 +190,16 @@ class AuthMiddleware(BaseHTTPMiddleware):
205
190
  # 从请求头获取服务认证信息(可选)
206
191
  server_ak = request.headers.get("SERVER-AK", "")
207
192
  server_sk = request.headers.get("SERVER-SK", "")
193
+ machine_token = request.headers.get("MACHINE-TOKEN", "")
208
194
 
209
195
  # 调用IAM验证接口(即使token为空也要调用,因为可能是白名单接口)
210
- user_info = iam_client.verify_token(
196
+ user_info = self.iam_client.verify_token(
211
197
  token=token or "", # 如果token为None,传递空字符串
212
198
  api=api_path,
213
199
  method=method,
214
200
  server_ak=server_ak,
215
- server_sk=server_sk
201
+ server_sk=server_sk,
202
+ machine_token=machine_token
216
203
  )
217
204
 
218
205
  return user_info
@@ -222,12 +209,8 @@ class AuthMiddleware(BaseHTTPMiddleware):
222
209
  raise
223
210
  except Exception as e:
224
211
  logger.error(f"Token验证异常: {str(e)}")
225
- try:
226
- config, _ = self._get_config_and_client()
227
- if config.enable_debug:
228
- logger.exception("详细异常信息:")
229
- except:
230
- pass
212
+ if self.config.enable_debug:
213
+ logger.exception("详细异常信息:")
231
214
  return None
232
215
 
233
216
  def _create_error_response(
@@ -279,22 +262,24 @@ class AuthService:
279
262
  """验证token和权限"""
280
263
  # 通过token, server_ak, server_sk判断是否有权限
281
264
  api_path = request.url.path
282
-
265
+
283
266
  # 首先检查路径是否在白名单中
284
267
  if self.is_path_whitelisted(api_path):
285
268
  logger.info(f"路径 {api_path} 在白名单中,跳过IAM鉴权")
286
269
  return True
287
-
270
+
288
271
  credentials: HTTPAuthorizationCredentials = await self.security(request)
289
272
  method = request.method
290
273
 
291
274
  server_ak = request.headers.get("SERVER-AK", "")
292
275
  server_sk = request.headers.get("SERVER-SK", "")
276
+ machine_token = request.headers.get("MACHINE-TOKEN", "")
277
+ print("248 machine_token:", machine_token)
293
278
 
294
279
  token = ""
295
280
  if credentials is not None:
296
281
  token = credentials.credentials
297
- user_info_by_iam = self.iam_client.verify_token(token, api_path, method, server_ak, server_sk)
282
+ user_info_by_iam = self.iam_client.verify_token(token, api_path, method, server_ak, server_sk, machine_token)
298
283
  if user_info_by_iam:
299
284
  return True
300
285
  return False
@@ -310,7 +295,7 @@ class AuthService:
310
295
  credentials: HTTPAuthorizationCredentials = await self.security(request)
311
296
  if not credentials:
312
297
  return None
313
-
298
+
314
299
  token = credentials.credentials
315
300
 
316
301
  # 直接解析JWT token获取payload
@@ -433,93 +418,32 @@ auth_service = None
433
418
 
434
419
  def setup_auth_middleware(auth_config: AuthConfig) -> None:
435
420
  """
436
- 设置认证中间件配置(向后兼容)
421
+ 设置认证中间件配置
437
422
 
438
423
  Args:
439
424
  auth_config: 认证配置实例,包含白名单路径等配置
440
-
441
- Deprecated:
442
- 请使用 init_skyplatform_iam() 替代
443
425
  """
444
426
  global auth_service
445
427
  auth_service = AuthService(auth_config)
446
- logger.warning("setup_auth_middleware()已废弃,请使用init_skyplatform_iam()替代")
447
428
  logger.info(f"认证中间件已配置,白名单路径数量: {len(auth_config.get_whitelist_paths())}")
448
429
 
449
430
 
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
431
  # 便捷的依赖函数
477
432
  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
- # 传统模式(向后兼容)
433
+ """获取当前用户的依赖函数"""
498
434
  if auth_service is None:
499
435
  raise HTTPException(
500
436
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
501
- detail="认证服务未初始化,请先调用init_skyplatform_iam()或setup_auth_middleware()函数进行配置"
437
+ detail="认证服务未初始化,请先调用setup_auth_middleware函数进行配置"
502
438
  )
503
439
  return await auth_service.require_auth(request)
504
440
 
505
441
 
506
442
  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
- # 传统模式(向后兼容)
443
+ """获取可选当前用户的依赖函数"""
520
444
  if auth_service is None:
521
445
  raise HTTPException(
522
446
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
523
- detail="认证服务未初始化,请先调用init_skyplatform_iam()或setup_auth_middleware()函数进行配置"
447
+ detail="认证服务未初始化,请先调用setup_auth_middleware函数进行配置"
524
448
  )
525
449
  return await auth_service.optional_auth(request)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skyplatform-iam
3
- Version: 1.0.5
3
+ Version: 1.2.0
4
4
  Summary: SkyPlatform IAM认证SDK,提供FastAPI中间件和认证路由
5
5
  Project-URL: Homepage, https://github.com/xinmayoujiang12621/agenterra_iam
6
6
  Project-URL: Documentation, https://skyplatform-iam.readthedocs.io/
@@ -0,0 +1,8 @@
1
+ skyplatform_iam/__init__.py,sha256=N4acauQXv5CUHNgaeYc3wCTi9zlwt9xvZW5szZ-ahkc,4664
2
+ skyplatform_iam/config.py,sha256=4EOzjevFtQ25tZPK7wpU58W6hD-B_XVQF7VCNQzdVOM,4429
3
+ skyplatform_iam/connect_agenterra_iam.py,sha256=ixnk45JQoILfwVVKdPllLO-xUqGb8moOh0G6sAIvrVU,40712
4
+ skyplatform_iam/exceptions.py,sha256=Rt55QIzVK1F_kn6yzKQKKakD6PZDFdPLCGaCphKKms8,2166
5
+ skyplatform_iam/middleware.py,sha256=e_YNRWXmDVKeKwpAcFYptTV4WZboAF-ICC5p9rvLSE0,17069
6
+ skyplatform_iam-1.2.0.dist-info/METADATA,sha256=T7kVHT53D8WXPJTomoWc6nDNIS3ZM2SYGVDX_r26JGY,12658
7
+ skyplatform_iam-1.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
8
+ skyplatform_iam-1.2.0.dist-info/RECORD,,