mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-05-17 22:22:45 +02:00
Integrate new provider verifier into providers
This commit is contained in:
parent
e3678aaaff
commit
1f992b3f87
@ -2,17 +2,12 @@ package providers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/v3/oidc"
|
|
||||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
||||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
|
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
|
||||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
|
|
||||||
internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
|
internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
|
||||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests"
|
|
||||||
k8serrors "k8s.io/apimachinery/pkg/util/errors"
|
k8serrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -86,16 +81,27 @@ func newProviderDataFromConfig(providerConfig options.Provider) (*ProviderData,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if needsVerifier {
|
if needsVerifier {
|
||||||
oidcProvider, verifier, err := newOIDCProviderVerifier(providerConfig)
|
pv, err := internaloidc.NewProviderVerifier(context.TODO(), internaloidc.ProviderVerifierOptions{
|
||||||
|
AudienceClaims: providerConfig.OIDCConfig.AudienceClaims,
|
||||||
|
ClientID: providerConfig.ClientID,
|
||||||
|
ExtraAudiences: providerConfig.OIDCConfig.ExtraAudiences,
|
||||||
|
IssuerURL: providerConfig.OIDCConfig.IssuerURL,
|
||||||
|
JWKsURL: providerConfig.OIDCConfig.JwksURL,
|
||||||
|
SkipDiscovery: providerConfig.OIDCConfig.SkipDiscovery,
|
||||||
|
SkipIssuerVerification: providerConfig.OIDCConfig.InsecureSkipIssuerVerification,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error setting OIDC configuration: %v", err)
|
return nil, fmt.Errorf("error building OIDC ProviderVerifier: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Verifier = verifier
|
p.Verifier = pv.Verifier()
|
||||||
if oidcProvider != nil {
|
if pv.DiscoveryEnabled() {
|
||||||
// Use the discovered values rather than any specified values
|
// Use the discovered values rather than any specified values
|
||||||
providerConfig.LoginURL = oidcProvider.Endpoint().AuthURL
|
endpoints := pv.Provider().Endpoints()
|
||||||
providerConfig.RedeemURL = oidcProvider.Endpoint().TokenURL
|
providerConfig.LoginURL = endpoints.AuthURL
|
||||||
|
providerConfig.RedeemURL = endpoints.TokenURL
|
||||||
|
providerConfig.ProfileURL = endpoints.UserInfoURL
|
||||||
|
providerConfig.OIDCConfig.JwksURL = endpoints.JWKsURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,118 +165,3 @@ func providerRequiresOIDCProviderVerifier(providerType options.ProviderType) (bo
|
|||||||
return false, fmt.Errorf("unknown provider type: %s", providerType)
|
return false, fmt.Errorf("unknown provider type: %s", providerType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOIDCProviderVerifier(providerConfig options.Provider) (*oidc.Provider, internaloidc.IDTokenVerifier, error) {
|
|
||||||
// If the issuer isn't set, default it for platforms where it makes sense
|
|
||||||
if providerConfig.OIDCConfig.IssuerURL == "" {
|
|
||||||
switch providerConfig.Type {
|
|
||||||
case "gitlab":
|
|
||||||
providerConfig.OIDCConfig.IssuerURL = "https://gitlab.com"
|
|
||||||
case "oidc":
|
|
||||||
return nil, nil, errors.New("missing required setting: OIDC Issuer URL cannot be empty")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case providerConfig.OIDCConfig.InsecureSkipIssuerVerification && !providerConfig.OIDCConfig.SkipDiscovery:
|
|
||||||
verifier, err := newInsecureSkipIssuerVerificationOIDCVerifier(providerConfig)
|
|
||||||
return nil, verifier, err
|
|
||||||
case providerConfig.OIDCConfig.SkipDiscovery:
|
|
||||||
verifier, err := newSkipDiscoveryOIDCVerifier(providerConfig)
|
|
||||||
return nil, verifier, err
|
|
||||||
default:
|
|
||||||
return newDiscoveryOIDCProviderVerifier(providerConfig)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDiscoveryOIDCProviderVerifier(providerConfig options.Provider) (*oidc.Provider, internaloidc.IDTokenVerifier, error) {
|
|
||||||
// Configure discoverable provider data.
|
|
||||||
provider, err := oidc.NewProvider(context.TODO(), providerConfig.OIDCConfig.IssuerURL)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
verificationOptions := internaloidc.IDTokenVerificationOptions{
|
|
||||||
AudienceClaims: providerConfig.OIDCConfig.AudienceClaims,
|
|
||||||
ClientID: providerConfig.ClientID,
|
|
||||||
ExtraAudiences: providerConfig.OIDCConfig.ExtraAudiences,
|
|
||||||
}
|
|
||||||
verifier := internaloidc.NewVerifier(provider.Verifier(&oidc.Config{
|
|
||||||
ClientID: providerConfig.ClientID,
|
|
||||||
SkipIssuerCheck: providerConfig.OIDCConfig.InsecureSkipIssuerVerification,
|
|
||||||
SkipClientIDCheck: true, // client id check is done within oauth2-proxy: IDTokenVerifier.Verify
|
|
||||||
}), verificationOptions)
|
|
||||||
|
|
||||||
return provider, verifier, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newInsecureSkipIssuerVerificationOIDCVerifier(providerConfig options.Provider) (internaloidc.IDTokenVerifier, error) {
|
|
||||||
// go-oidc doesn't let us pass bypass the issuer check this in the oidc.NewProvider call
|
|
||||||
// (which uses discovery to get the URLs), so we'll do a quick check ourselves and if
|
|
||||||
// we get the URLs, we'll just use the non-discovery path.
|
|
||||||
|
|
||||||
logger.Printf("Performing OIDC Discovery...")
|
|
||||||
|
|
||||||
requestURL := strings.TrimSuffix(providerConfig.OIDCConfig.IssuerURL, "/") + "/.well-known/openid-configuration"
|
|
||||||
body, err := requests.New(requestURL).
|
|
||||||
Do().
|
|
||||||
UnmarshalJSON()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to discover OIDC configuration: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prefer manually configured URLs. It's a bit unclear
|
|
||||||
// why you'd be doing discovery and also providing the URLs
|
|
||||||
// explicitly though...
|
|
||||||
if providerConfig.LoginURL == "" {
|
|
||||||
providerConfig.LoginURL = body.Get("authorization_endpoint").MustString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if providerConfig.RedeemURL == "" {
|
|
||||||
providerConfig.RedeemURL = body.Get("token_endpoint").MustString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if providerConfig.OIDCConfig.JwksURL == "" {
|
|
||||||
providerConfig.OIDCConfig.JwksURL = body.Get("jwks_uri").MustString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if providerConfig.ProfileURL == "" {
|
|
||||||
providerConfig.ProfileURL = body.Get("userinfo_endpoint").MustString()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we have performed the discovery, construct the verifier manually
|
|
||||||
return newSkipDiscoveryOIDCVerifier(providerConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSkipDiscoveryOIDCVerifier(providerConfig options.Provider) (internaloidc.IDTokenVerifier, error) {
|
|
||||||
var errs []error
|
|
||||||
|
|
||||||
// Construct a manual IDTokenVerifier from issuer URL & JWKS URI
|
|
||||||
// instead of metadata discovery if we enable -skip-oidc-discovery.
|
|
||||||
// In this case we need to make sure the required endpoints for
|
|
||||||
// the provider are configured.
|
|
||||||
if providerConfig.LoginURL == "" {
|
|
||||||
errs = append(errs, errors.New("missing required setting: login-url"))
|
|
||||||
}
|
|
||||||
if providerConfig.RedeemURL == "" {
|
|
||||||
errs = append(errs, errors.New("missing required setting: redeem-url"))
|
|
||||||
}
|
|
||||||
if providerConfig.OIDCConfig.JwksURL == "" {
|
|
||||||
errs = append(errs, errors.New("missing required setting: oidc-jwks-url"))
|
|
||||||
}
|
|
||||||
if len(errs) > 0 {
|
|
||||||
return nil, k8serrors.NewAggregate(errs)
|
|
||||||
}
|
|
||||||
|
|
||||||
keySet := oidc.NewRemoteKeySet(context.TODO(), providerConfig.OIDCConfig.JwksURL)
|
|
||||||
verificationOptions := internaloidc.IDTokenVerificationOptions{
|
|
||||||
AudienceClaims: providerConfig.OIDCConfig.AudienceClaims,
|
|
||||||
ClientID: providerConfig.ClientID,
|
|
||||||
ExtraAudiences: providerConfig.OIDCConfig.ExtraAudiences,
|
|
||||||
}
|
|
||||||
verifier := internaloidc.NewVerifier(oidc.NewVerifier(providerConfig.OIDCConfig.IssuerURL, keySet, &oidc.Config{
|
|
||||||
ClientID: providerConfig.ClientID,
|
|
||||||
SkipIssuerCheck: providerConfig.OIDCConfig.InsecureSkipIssuerVerification,
|
|
||||||
SkipClientIDCheck: true, // client id check is done within oauth2-proxy: IDTokenVerifier.Verify
|
|
||||||
}), verificationOptions)
|
|
||||||
return verifier, nil
|
|
||||||
}
|
|
||||||
|
@ -87,7 +87,7 @@ func TestSkipOIDCDiscovery(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, err := newProviderDataFromConfig(providerConfig)
|
_, err := newProviderDataFromConfig(providerConfig)
|
||||||
g.Expect(err).To(MatchError("error setting OIDC configuration: [missing required setting: login-url, missing required setting: redeem-url, missing required setting: oidc-jwks-url]"))
|
g.Expect(err).To(MatchError("error building OIDC ProviderVerifier: invalid provider verifier options: missing required setting: jwks-url"))
|
||||||
|
|
||||||
providerConfig.LoginURL = msAuthURL
|
providerConfig.LoginURL = msAuthURL
|
||||||
providerConfig.RedeemURL = msTokenURL
|
providerConfig.RedeemURL = msTokenURL
|
||||||
|
Loading…
x
Reference in New Issue
Block a user