diff --git a/go.mod b/go.mod index c928ddc..e6823e3 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,8 @@ require ( gopkg.in/yaml.v3 v3.0.1 // yaml parsing for different config files ) +replace github.com/coreos/go-oidc/v3 => github.com/godoxy-app/go-oidc/v3 v3.14.1 + require ( github.com/docker/cli v28.1.1+incompatible github.com/docker/go-connections v0.5.0 diff --git a/go.sum b/go.sum index 3d29072..f383677 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,6 @@ github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9F github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk= -github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -68,6 +66,8 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godoxy-app/go-oidc/v3 v3.14.1 h1:QWes6QTEeyZQ40fluO8HLqF/D9W0Nj/Zm7UYhTTUJ+k= +github.com/godoxy-app/go-oidc/v3 v3.14.1/go.mod h1:ZRZLrEz7MmMe1kRzRsYqYmWKN2EHlPVGn71GMbrLLt4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= diff --git a/internal/api/v1/auth/oidc.go b/internal/api/v1/auth/oidc.go index 65534cd..8baa1f0 100644 --- a/internal/api/v1/auth/oidc.go +++ b/internal/api/v1/auth/oidc.go @@ -4,19 +4,16 @@ import ( "context" "crypto/rand" "encoding/base64" - "encoding/json" "errors" "fmt" - "io" - "mime" "net/http" "net/url" "slices" - "strings" "time" "github.com/coreos/go-oidc/v3/oidc" "github.com/yusing/go-proxy/internal/common" + "github.com/yusing/go-proxy/internal/logging" "github.com/yusing/go-proxy/internal/net/gphttp" "github.com/yusing/go-proxy/internal/utils" "github.com/yusing/go-proxy/internal/utils/strutils" @@ -51,46 +48,20 @@ func NewOIDCProvider(issuerURL, clientID, clientSecret, redirectURL string, allo if len(allowedUsers)+len(allowedGroups) == 0 { return nil, errors.New("OIDC users, groups, or both must not be empty") } - - wellKnown := strings.TrimSuffix(issuerURL, "/") + "/.well-known/openid-configuration" - resp, err := gphttp.Get(wellKnown) + provider, err := oidc.NewProvider(context.Background(), issuerURL) if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("oidc: unable to read response body: %v", err) + return nil, fmt.Errorf("failed to initialize OIDC provider: %w", err) } - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("oidc: %s: %s", resp.Status, body) + endSessionURL, err := url.Parse(provider.EndSessionEndpoint()) + if err != nil && provider.EndSessionEndpoint() != "" { + // non critical, just warn + logging.Warn(). + Str("issuer", issuerURL). + Err(err). + Msg("failed to parse end session URL") } - var p providerJSON - err = json.Unmarshal(body, &p) - if err != nil { - mimeType, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) - if err == nil && mimeType != "application/json" { - return nil, fmt.Errorf("oidc: unexpected content type: %q from OIDC provider discovery, have you configured the correct issuer URL?", mimeType) - } - return nil, fmt.Errorf("oidc: failed to decode provider discovery object: %v", err) - } - - if p.IssuerURL != issuerURL { - return nil, fmt.Errorf("oidc: issuer did not match the issuer returned by provider, expected %q got %q", issuerURL, p.IssuerURL) - } - - var endSessionURL *url.URL - if p.EndSessionURL != "" { - endSessionURL, err = url.Parse(p.EndSessionURL) - if err != nil { - return nil, fmt.Errorf("oidc: failed to parse end session URL: %w", err) - } - } - - provider := p.NewProvider(context.Background()) return &OIDCProvider{ oauthConfig: &oauth2.Config{ ClientID: clientID,