87 lines
4.5 KiB
Bash
Executable File
87 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# DeepData × Casdoor SSO 全链路 E2E 检查(在能同时访问网关与 Casdoor 的机器上运行)
|
||
#
|
||
# 用法:
|
||
# GW_BASE=https://deepdata.yhdd.apescale.com:1014 \
|
||
# CASDOOR_BASE=http://192.168.31.23:1013 \
|
||
# SSO_CLIENT_ID=<clientId> SSO_CLIENT_SECRET=<secret> \
|
||
# LOCAL_ADMIN_PASSWORD=*** \
|
||
# bash e2e-check.sh
|
||
#
|
||
# 可选环境变量(有默认值,按实际部署修改):
|
||
# SSO_APP_NAME=DataMate Casdoor 应用名
|
||
# SSO_APP_OWNER=admin Casdoor 应用 owner(grant-consent 需 owner/name 全名)
|
||
# SSO_ORG=datamate Casdoor 组织名(登录用)
|
||
# SSO_REDIRECT_URI=$GW_BASE/api/user/oauth/callback
|
||
# SSO_TEST_USERS="dmin:Dmin@2026:admin viewer1:Viewer1@2026:viewer" 用户名:密码:期望角色
|
||
# LOCAL_ADMIN=admin 本地管理员(验证本地登录共存)
|
||
set -u
|
||
|
||
GW="${GW_BASE:?GW_BASE required, e.g. https://deepdata.yhdd.apescale.com:1014}"
|
||
CD="${CASDOOR_BASE:?CASDOOR_BASE required, e.g. http://192.168.31.23:1013}"
|
||
APP="${SSO_APP_NAME:-DataMate}"
|
||
APP_FULL="${SSO_APP_OWNER:-admin}/$APP"
|
||
ORG="${SSO_ORG:-datamate}"
|
||
REDIR="${SSO_REDIRECT_URI:-$GW/api/user/oauth/callback}"
|
||
CLIENT_ID="${SSO_CLIENT_ID:?SSO_CLIENT_ID required}"
|
||
ADMIN_U="${LOCAL_ADMIN:-admin}"
|
||
ADMIN_P="${LOCAL_ADMIN_PASSWORD:*** LOCAL_ADMIN_PASSWORD required}"
|
||
|
||
TMPD=$(mktemp -d); trap 'rm -rf "$TMPD"' EXIT
|
||
fail=0
|
||
ck() { if [ "$1" = "0" ]; then echo "PASS: $2"; else echo "FAIL: $2"; fail=1; fi; }
|
||
|
||
echo "=== [1] /sso/casdoor/config ==="
|
||
CFG=$(curl -sk "$GW/sso/casdoor/config")
|
||
echo "$CFG"
|
||
echo "$CFG" | grep -q '"enabled":true' && ck 0 "enabled=true" || ck 1 "enabled"
|
||
# clientSecret 不得出现在公开配置里
|
||
if [ -n "${SSO_CLIENT_SECRET:-}" ] && echo "$CFG" | grep -q "$SSO_CLIENT_SECRET"; then
|
||
ck 1 "clientSecret 泄漏"; else ck 0 "无 secret 泄漏"; fi
|
||
|
||
echo "=== [2] 本地登录 $ADMIN_U(accountOnly 已移除,本地登录与 SSO 共存)==="
|
||
LOGIN=$(curl -sk -X POST "$GW/api/user/login" -H 'Content-Type: application/json' \
|
||
-d "{\"username\":\"$ADMIN_U\",\"password\":\"$ADMIN_P\"}")
|
||
TOK=$(echo "$LOGIN" | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')
|
||
[ -n "$TOK" ] && ck 0 "本地登录拿 token" || { echo "$LOGIN"; ck 1 "本地登录"; }
|
||
ME=$(curl -sk "$GW/api/user/me" -H "Authorization: Bearer $TOK")
|
||
echo "$ME"
|
||
|
||
# SSO 单用户链路: 网关登录页 → casdoor JSON 登录 → grant-consent 取 code → 网关 callback → /me
|
||
sso_test() {
|
||
local U="$1" P="$2" EXPECT="$3"
|
||
local GJ="$TMPD/gw_$U" CJ="$TMPD/cd_$U" HDRS AUTHURL STATE LR CODE CB FINAL SSTOK ME2
|
||
HDRS=$(curl -sk -c "$GJ" -D - -o /dev/null "$GW/api/user/oauth/login?next=/sso/callback.html")
|
||
AUTHURL=$(echo "$HDRS" | grep -i '^location:' | tr -d '\r' | awk '{print $2}')
|
||
STATE=$(echo "$AUTHURL" | sed -n 's/.*state=\([^&]*\).*/\1/p')
|
||
[ -n "$AUTHURL" ] && [ -n "$STATE" ] && ck 0 "$U 拿到 authorize URL" || { echo "authurl=$AUTHURL"; ck 1 "$U authorize"; return; }
|
||
LR=$(curl -s -c "$CJ" -X POST -H 'Content-Type: application/json' \
|
||
-d "{\"type\":\"login\",\"application\":\"$APP\",\"username\":\"$U\",\"password\":\"$P\",\"organization\":\"$ORG\",\"autoSignin\":true}" \
|
||
"$CD/api/login")
|
||
echo "$LR" | grep -q '"status": *"ok"' && ck 0 "$U casdoor 登录" || { echo "$LR"; ck 1 "$U casdoor 登录"; return; }
|
||
CODE=$(curl -s -b "$CJ" -X POST -H 'Content-Type: application/json' \
|
||
-d "{\"application\":\"$APP_FULL\",\"clientId\":\"$CLIENT_ID\",\"provider\":\"\",\"signinMethod\":\"\",\"responseType\":\"code\",\"redirectUri\":\"$REDIR\",\"scope\":\"openid profile email\",\"state\":\"$STATE\",\"nonce\":\"\",\"challenge\":\"\",\"resource\":\"\"}" \
|
||
"$CD/api/grant-consent" | sed -n 's/.*"data": *"\([^"]*\)".*/\1/p')
|
||
[ -n "$CODE" ] && ck 0 "$U 拿到 authorization code" || { ck 1 "$U grant-consent"; return; }
|
||
CB=$(curl -sk -b "$GJ" -D - -o /dev/null "$GW/api/user/oauth/callback?code=$CODE&state=$STATE")
|
||
FINAL=$(echo "$CB" | grep -i '^location:' | tr -d '\r' | awk '{print $2}')
|
||
echo "final: $FINAL"
|
||
SSTOK=$(echo "$FINAL" | sed -n 's/.*sso_token=//p')
|
||
[ -n "$SSTOK" ] && ck 0 "$U 拿到 sso_token" || { echo "$CB" | head -5; ck 1 "$U sso_token"; return; }
|
||
ME2=$(curl -sk "$GW/api/user/me" -H "Authorization: Bearer $SSTOK")
|
||
echo "$ME2"
|
||
echo "$ME2" | grep -q "\"role\":\"$EXPECT\"" && ck 0 "$U 角色=$EXPECT" || ck 1 "$U 角色(期望 $EXPECT)"
|
||
}
|
||
|
||
i=3
|
||
for entry in ${SSO_TEST_USERS:-}; do
|
||
U="${entry%%:*}"; rest="${entry#*:}"; P="${rest%%:*}"; EXPECT="${rest#*:}"
|
||
echo "=== [$i] SSO $U → $EXPECT ==="
|
||
sso_test "$U" "$P" "$EXPECT"
|
||
i=$((i+1))
|
||
done
|
||
|
||
echo ""
|
||
echo "=== 汇总 fail=$fail ==="
|
||
exit "$fail"
|