Skip to content

Commit

Permalink
fix(tenant): add tenant mode/id for jwt app, and tenant_id for jwt us…
Browse files Browse the repository at this point in the history
…er (#206)
  • Loading branch information
wklken authored Dec 24, 2024
1 parent a1fa355 commit 9b78eb9
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 14 deletions.
2 changes: 1 addition & 1 deletion sdks/apigw-manager/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "apigw-manager"
version = "4.0.0"
version = "4.0.1"
description = "The SDK for managing blueking gateway resource."
readme = "README.md"
authors = ["blueking <[email protected]>"]
Expand Down
24 changes: 18 additions & 6 deletions sdks/apigw-manager/src/apigw_manager/apigw/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,17 @@ class ApiGatewayJWTGenericMiddleware(ApiGatewayJWTMiddleware):
class ApiGatewayJWTAppMiddleware:
"""Read the JWT information to set the request.app attribute"""

App = namedtuple("App", ["bk_app_code", "verified"])
App = namedtuple("App", ["bk_app_code", "verified", "tenant_mode", "tenant_id"])

def __init__(self, get_response):
self.get_response = get_response

def make_app(self, bk_app_code=None, verified=False, **jwt_app):
def make_app(self, bk_app_code=None, verified=False, tenant_mode="", tenant_id="", **jwt_app):
return self.App(
bk_app_code=bk_app_code,
verified=verified,
tenant_mode=tenant_mode,
tenant_id=tenant_id,
)

def __call__(self, request):
Expand All @@ -111,13 +113,18 @@ class ApiGatewayJWTUserMiddleware:
def __init__(self, get_response):
self.get_response = get_response

def get_user(self, request, gateway_name=None, bk_username=None, verified=False, **credentials):
def get_user(self, request, gateway_name=None, bk_username=None, tenant_id=None, verified=False, **credentials):
# 传递 gateway_name 参数的用途:
# 1. 来明确标识这个请求来自于网关
# 2. 用户已经过认证,后端无需再认证
# 3. 避免非预期调用激活对应后端使得用户认证被绕过
return auth.authenticate(
request, gateway_name=gateway_name, bk_username=bk_username, verified=verified, **credentials
request,
gateway_name=gateway_name,
bk_username=bk_username,
tenant_id=tenant_id,
verified=verified,
**credentials,
)

def __call__(self, request):
Expand Down Expand Up @@ -151,9 +158,14 @@ def __init__(self):
def make_anonymous_user(self, bk_username=None):
user = AnonymousUser()
user.username = bk_username # type: ignore
# set the tenant_id
user.tenant_id = "" # type: ignore
return user

def authenticate(self, request, gateway_name, bk_username, verified, **credentials):
def authenticate(self, request, gateway_name, bk_username, tenant_id, verified, **credentials):
if not verified:
return self.make_anonymous_user(bk_username=bk_username)
return self.user_maker(bk_username)

user = self.user_maker(bk_username)
user.tenant_id = tenant_id # type: ignore
return user
3 changes: 3 additions & 0 deletions sdks/apigw-manager/src/apigw_manager/core/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ def _call(self, operation, files=None, **kwargs):
"data": kwargs,
"headers": {
"X-Bkapi-Authorization": kwargs.pop("x_bkapi_authorization", self._get_bkapi_authorization()),
# the header is required by the API gateway plugin bk-tenant-validate, for global tenant app!
# so we set it to system, it would not be used in the gateway
"X-Bk-Tenant-Id": "system",
},
"files": files,
}
Expand Down
11 changes: 7 additions & 4 deletions sdks/apigw-manager/src/apigw_manager/drf/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@
from collections import namedtuple
from typing import ClassVar, Type

from apigw_manager.apigw.providers import CachePublicKeyProvider, PublicKeyProvider
from apigw_manager.apigw.utils import get_configuration
from django.conf import settings
from django.contrib import auth
from django.utils.module_loading import import_string
from rest_framework.authentication import BaseAuthentication

from apigw_manager.apigw.providers import CachePublicKeyProvider, PublicKeyProvider
from apigw_manager.apigw.utils import get_configuration

logger = logging.getLogger(__name__)

App = namedtuple("App", ["bk_app_code", "verified"])
App = namedtuple("App", ["bk_app_code", "verified", "tenant_mode", "tenant_id"])


class ApiGatewayJWTAuthentication(BaseAuthentication):
Expand Down Expand Up @@ -81,10 +82,12 @@ def authenticate(self, request):
def authenticate_header(self, request):
return self.JWT_KEY_NAME

def make_app(self, bk_app_code=None, verified=False, **jwt_app) -> App:
def make_app(self, bk_app_code=None, verified=False, tenant_mode="", tenant_id="", **jwt_app) -> App:
return App(
bk_app_code=bk_app_code,
verified=verified,
tenant_mode=tenant_mode,
tenant_id=tenant_id,
)

def get_user(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from apigw_manager.apigw import authentication, providers
from apigw_manager.apigw.providers import CachePublicKeyProvider, DefaultJWTProvider, SettingsPublicKeyProvider


@pytest.fixture()
def mock_response(mocker):
return mocker.MagicMock()
Expand Down Expand Up @@ -243,13 +242,17 @@ def _setup_backend(self):
self.backend = authentication.UserModelBackend()

def test_authenticate_user(self, mock_request):
user = self.backend.authenticate(mock_request, gateway_name="test", bk_username="admin", verified=True)
user = self.backend.authenticate(
mock_request, gateway_name="test", bk_username="admin", tenant_id="system", verified=True
)
assert not isinstance(user, AnonymousUser)
assert user.username == "admin"
assert user.is_authenticated is True

def test_authenticate_anonymous_user(self, mock_request):
user = self.backend.authenticate(mock_request, gateway_name="test", bk_username="admin", verified=False)
user = self.backend.authenticate(
mock_request, gateway_name="test", bk_username="admin", tenant_id="system", verified=False
)
assert isinstance(user, AnonymousUser)
assert user.username == "admin"
assert user.is_authenticated is False

0 comments on commit 9b78eb9

Please sign in to comment.