fix(apiserver): match JWT-excluded paths exactly, wildcard only for /* (bug-1962)

Cause: isExcludedPath (middleware/validatehandler.go) dropped the last
character of every excluded entry and prefix-matched, so /ping excused any
path starting with /pin (e.g. /pinX) from JWT validation, while
/swagger/*any (trimmed to /swagger/*an) never matched.

Fix: entries match exactly; an entry whose last segment is a gin catch-all
(/swagger/*any) matches any path under the part before the "*".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-10-10 10:23:05 +00:00
parent d720132c8c
commit 387a421c57
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
2 changed files with 76 additions and 14 deletions

View file

@ -44,23 +44,30 @@ func ValidateHandler() gin.HandlerFunc {
}
}
func isExcludedPath(path string) bool {
// jwtExcludedPaths are the routes that skip JWT validation. An entry is
// matched exactly, unless its last segment is a gin catch-all ("*name", as in
// the route "/swagger/*any"): then any path under the part before the "*"
// matches (bug-1962).
var jwtExcludedPaths = []string{
"/ping",
"/xce/v1/auth/logon",
"/swagger/*any",
"/xce/v1/auth/logout",
}
allowed := false
// define some excluded paths
excludedPaths := []string{
"/ping",
"/xce/v1/auth/logon",
"/swagger/*any",
"/xce/v1/auth/logout",
}
for _, excludedPath := range excludedPaths {
if strings.HasPrefix(path, excludedPath[:len(excludedPath)-1]) { // 去掉最后的 *
allowed = true
break
func isExcludedPath(path string) bool {
for _, excludedPath := range jwtExcludedPaths {
if i := strings.LastIndex(excludedPath, "/*"); i >= 0 {
if strings.HasPrefix(path, excludedPath[:i+1]) {
return true
}
continue
}
if path == excludedPath {
return true
}
}
return allowed
return false
}
// Token validation middleware