feat(embedded): aud claim and type for guest token (#18651)

* add aud claim and type for guest token

* update test

* lint

* make jwt audience configurable

* lint

* Apply suggestions from code review

Co-authored-by: David Aaron Suddjian <1858430+suddjian@users.noreply.github.com>

* verify aud

* add tests for aud and type claim

Co-authored-by: David Aaron Suddjian <1858430+suddjian@users.noreply.github.com>
This commit is contained in:
Lily Kuang
2022-02-14 10:43:35 -08:00
committed by GitHub
parent 4001165f55
commit e6ea197e9f
4 changed files with 72 additions and 3 deletions

View File

@@ -74,6 +74,7 @@ from superset.security.guest_token import (
GuestUser,
)
from superset.utils.core import DatasourceName, RowLevelSecurityFilterType
from superset.utils.urls import get_url_host
if TYPE_CHECKING:
from superset.common.query_context import QueryContext
@@ -1308,6 +1309,7 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
secret = current_app.config["GUEST_TOKEN_JWT_SECRET"]
algo = current_app.config["GUEST_TOKEN_JWT_ALGO"]
exp_seconds = current_app.config["GUEST_TOKEN_JWT_EXP_SECONDS"]
aud = current_app.config["GUEST_TOKEN_JWT_AUDIENCE"] or get_url_host()
# calculate expiration time
now = self._get_current_epoch_time()
@@ -1319,6 +1321,8 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
# standard jwt claims:
"iat": now, # issued at
"exp": exp, # expiration time
"aud": aud,
"type": "guest",
}
token = jwt.encode(claims, secret, algorithm=algo)
return token
@@ -1344,6 +1348,8 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
raise ValueError("Guest token does not contain a resources claim")
if token.get("rls_rules") is None:
raise ValueError("Guest token does not contain an rls_rules claim")
if token.get("type") != "guest":
raise ValueError("This is not a guest token.")
except Exception: # pylint: disable=broad-except
# The login manager will handle sending 401s.
# We don't need to send a special error message.
@@ -1366,7 +1372,8 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
"""
secret = current_app.config["GUEST_TOKEN_JWT_SECRET"]
algo = current_app.config["GUEST_TOKEN_JWT_ALGO"]
return jwt.decode(raw_token, secret, algorithms=[algo])
aud = current_app.config["GUEST_TOKEN_JWT_AUDIENCE"] or get_url_host()
return jwt.decode(raw_token, secret, algorithms=[algo], audience=aud)
@staticmethod
def is_guest_user(user: Optional[Any] = None) -> bool: