feat(auth): allow JWT IP changes by configuration (#1236)

* feat(auth): allow JWT IP changes by configuration

* fix(auth): make JWT IP change setting concurrency-safe

* test(auth): move JWT IP change setting tests out of MCP test file
This commit is contained in:
NikoCat233 authored and GitHub committed 2026-09-12 22:59:17 +08:00
1 parent 8cb86e3853
commit d19952a834
8 files changed
+172 -2

No files matched your search

@@ -193,6 +193,61 @@ func TestIdentityHandlerFlagsIPMismatch(t *testing.T) {
assert.True(t, verify.GetBool(model.CtxKeyIsIPMismatch))
}
func TestIdentityHandlerAllowsIPMismatchWhenConfigured(t *testing.T) {
cleanup := setupJWTSessionTest(t)
defer cleanup()
singleton.Conf.SetJWTIPChangeAllowed(true)
ctx := newCtxForUser(0, "1.2.3.4", "ua")
user := model.User{Common: model.Common{ID: 100}, TokenVersion: 7}
claims, err := issueJWTSession(ctx, &user, 1)
require.NoError(t, err)
verify := newCtxForUser(0, "9.9.9.9", "ua")
verify.Set("JWT_PAYLOAD", jwt.MapClaims{
jwtClaimUserID: claims[jwtClaimUserID],
jwtClaimKeyID: claims[jwtClaimKeyID],
})
identity := identityHandler()(verify)
require.NotNil(t, identity, "IP mismatch must be accepted when allow_jwt_ip_change is enabled")
assert.False(t, verify.GetBool(model.CtxKeyIsIPMismatch))
}
func TestIdentityHandlerConcurrentIPChangeSetting(t *testing.T) {
cleanup := setupJWTSessionTest(t)
defer cleanup()
ctx := newCtxForUser(0, "1.2.3.4", "ua")
user := model.User{Common: model.Common{ID: 100}, TokenVersion: 7}
claims, err := issueJWTSession(ctx, &user, 1)
require.NoError(t, err)
stop, done := make(chan struct{}), make(chan struct{})
go func() {
defer close(done)
for {
select {
case <-stop:
return
default:
singleton.Conf.SetJWTIPChangeAllowed(true)
singleton.Conf.SetJWTIPChangeAllowed(false)
}
}
}()
defer func() {
close(stop)
<-done
}()
for i := 0; i < 100; i++ {
verify := newCtxForUser(0, "1.2.3.4", "ua")
verify.Set("JWT_PAYLOAD", jwt.MapClaims(claims))
require.NotNil(t, identityHandler()(verify), "matching IP must pass during setting updates")
}
}
func TestIdentityHandlerRejectsUnknownKeyID(t *testing.T) {
cleanup := setupJWTSessionTest(t)
defer cleanup()