fix(19.7): RA-IN-02 stream bearer re-checks carry the client address
The stateful GET stream and the stateless subscriptions/listen stream capture the client address when they open and resolve every periodic re-check with towel.WithClientIP, as the bearer middleware does, so a failing re-check (a revoked admin token, for example) is logged with the remote address. TestStreamRecheckClientIP records the address the verifier sees on every verification of both streams.
This commit is contained in:
@@ -15,6 +15,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/towel"
|
||||
"github.com/modelcontextprotocol/go-sdk/auth"
|
||||
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
@@ -425,12 +426,15 @@ func (sr *sessionRouter) persist(ctx context.Context, ls *localSession) {
|
||||
// serveStream serves the standalone GET stream and re-verifies its bearer
|
||||
// every recheck interval on a goroutine that holds the raw bearer only for
|
||||
// the stream's lifetime; a bearer that no longer resolves to the session's
|
||||
// binding ends the stream (Pitfall 10). The server's base context ends
|
||||
// binding ends the stream (Pitfall 10). The re-check resolves with the
|
||||
// stream's client address on the context, as the bearer middleware does, so
|
||||
// a failed re-check is logged with it. The server's base context ends
|
||||
// every stream at shutdown.
|
||||
func (sr *sessionRouter) serveStream(w http.ResponseWriter, r *http.Request, ls *localSession) {
|
||||
ctx, cancel := context.WithCancel(r.Context())
|
||||
defer cancel()
|
||||
raw := bearerOf(r)
|
||||
ip := sr.p.clientIP(r)
|
||||
go func() {
|
||||
ticker := time.NewTicker(sr.p.recheck)
|
||||
defer ticker.Stop()
|
||||
@@ -439,7 +443,7 @@ func (sr *sessionRouter) serveStream(w http.ResponseWriter, r *http.Request, ls
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
id, err := sr.p.identities.resolve(ctx, raw)
|
||||
id, err := sr.p.identities.resolve(towel.WithClientIP(ctx, ip), raw)
|
||||
if err != nil || id.Binding != ls.binding {
|
||||
logSession(logger(), "stream_closed", ls.id, ls.binding)
|
||||
cancel()
|
||||
|
||||
Reference in New Issue
Block a user