mirror of
https://github.com/fatedier/frp.git
synced 2025-06-16 08:08:20 +00:00
Validate the subject in an oidc ping against a list of logged in subjects. This resolves the issue that multiple connected FRP clients with different OIDC clients result in a failing ping. The ping would fail because the subject in memory would be the value of the last logged in FRPC. This change also changes the constructor of OidcAuthVerifier to take a TokenVerifier interface. This will not change production behavior, but makes testing easier because we can inject a mock verifier during testing. Resolves: #4466
65 lines
1.7 KiB
Go
65 lines
1.7 KiB
Go
package auth_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/coreos/go-oidc/v3/oidc"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/fatedier/frp/pkg/auth"
|
|
v1 "github.com/fatedier/frp/pkg/config/v1"
|
|
"github.com/fatedier/frp/pkg/msg"
|
|
)
|
|
|
|
type mockTokenVerifier struct{}
|
|
|
|
func (m *mockTokenVerifier) Verify(ctx context.Context, subject string) (*oidc.IDToken, error) {
|
|
return &oidc.IDToken{
|
|
Subject: subject,
|
|
}, nil
|
|
}
|
|
|
|
func TestPingWithEmptySubjectFromLoginFails(t *testing.T) {
|
|
r := require.New(t)
|
|
consumer := auth.NewOidcAuthVerifier([]v1.AuthScope{v1.AuthScopeHeartBeats}, &mockTokenVerifier{})
|
|
err := consumer.VerifyPing(&msg.Ping{
|
|
PrivilegeKey: "ping-without-login",
|
|
Timestamp: time.Now().UnixMilli(),
|
|
})
|
|
r.Error(err)
|
|
r.Contains(err.Error(), "received different OIDC subject in login and ping")
|
|
}
|
|
|
|
func TestPingAfterLoginWithNewSubjectSucceeds(t *testing.T) {
|
|
r := require.New(t)
|
|
consumer := auth.NewOidcAuthVerifier([]v1.AuthScope{v1.AuthScopeHeartBeats}, &mockTokenVerifier{})
|
|
err := consumer.VerifyLogin(&msg.Login{
|
|
PrivilegeKey: "ping-after-login",
|
|
})
|
|
r.NoError(err)
|
|
|
|
err = consumer.VerifyPing(&msg.Ping{
|
|
PrivilegeKey: "ping-after-login",
|
|
Timestamp: time.Now().UnixMilli(),
|
|
})
|
|
r.NoError(err)
|
|
}
|
|
|
|
func TestPingAfterLoginWithDifferentSubjectFails(t *testing.T) {
|
|
r := require.New(t)
|
|
consumer := auth.NewOidcAuthVerifier([]v1.AuthScope{v1.AuthScopeHeartBeats}, &mockTokenVerifier{})
|
|
err := consumer.VerifyLogin(&msg.Login{
|
|
PrivilegeKey: "login-with-first-subject",
|
|
})
|
|
r.NoError(err)
|
|
|
|
err = consumer.VerifyPing(&msg.Ping{
|
|
PrivilegeKey: "ping-with-different-subject",
|
|
Timestamp: time.Now().UnixMilli(),
|
|
})
|
|
r.Error(err)
|
|
r.Contains(err.Error(), "received different OIDC subject in login and ping")
|
|
}
|