Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- [#486](https://github.com/oauth2-proxy/oauth2-proxy/pull/486) Add new linters (@johejo)
- [#440](https://github.com/oauth2-proxy/oauth2-proxy/pull/440) Switch Azure AD Graph API to Microsoft Graph API (@johejo)
- [#453](https://github.com/oauth2-proxy/oauth2-proxy/pull/453) Prevent browser caching during auth flow (@johejo)
- [#467](https://github.com/oauth2-proxy/oauth2-proxy/pull/467) Allow OIDC issuer verification to be skipped (@chkohner)
- [#481](https://github.com/oauth2-proxy/oauth2-proxy/pull/481) Update Okta docs (@trevorbox)
- [#474](https://github.com/oauth2-proxy/oauth2-proxy/pull/474) Always log hasMember request error object (@jbielick)
- [#468](https://github.com/oauth2-proxy/oauth2-proxy/pull/468) Implement graceful shutdown and propagate request context (@johejo)
Expand Down
1 change: 1 addition & 0 deletions docs/configuration/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ An example [oauth2-proxy.cfg]({{ site.gitweb }}/contrib/oauth2-proxy.cfg.example
| `-jwt-key-file` | string | path to the private key file in PEM format used to sign the JWT so that you can say something like `-jwt-key-file=/etc/ssl/private/jwt_signing_key.pem`: required by login.gov | |
| `-login-url` | string | Authentication endpoint | |
| `-insecure-oidc-allow-unverified-email` | bool | don't fail if an email address in an id_token is not verified | false |
| `-insecure-oidc-skip-issuer-verification` | bool | allow the OIDC issuer URL to differ from the expected (currently required for Azure multi-tenant compatibility) | false |
| `-oidc-issuer-url` | string | the OpenID Connect issuer URL. ie: `"https://accounts.google.com"` | |
| `-oidc-jwks-url` | string | OIDC JWKS URI for token verification; required if OIDC discovery is disabled | |
| `-pass-access-token` | bool | pass OAuth access_token to upstream via X-Forwarded-Access-Token header | false |
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ func main() {
flagSet.String("provider-display-name", "", "Provider display name")
flagSet.String("oidc-issuer-url", "", "OpenID Connect issuer URL (ie: https://accounts.google.com)")
flagSet.Bool("insecure-oidc-allow-unverified-email", false, "Don't fail if an email address in an id_token is not verified")
flagSet.Bool("insecure-oidc-skip-issuer-verification", false, "Do not verify if issuer matches OIDC discovery URL")
flagSet.Bool("skip-oidc-discovery", false, "Skip OIDC discovery and use manually supplied Endpoints")
flagSet.String("oidc-jwks-url", "", "OpenID Connect JWKS URL (ie: https://www.googleapis.com/oauth2/v3/certs)")
flagSet.String("login-url", "", "Authentication endpoint")
Expand Down
74 changes: 58 additions & 16 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
sessionsapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
"github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
"github.com/oauth2-proxy/oauth2-proxy/pkg/logger"
"github.com/oauth2-proxy/oauth2-proxy/pkg/requests"
"github.com/oauth2-proxy/oauth2-proxy/pkg/sessions"
"github.com/oauth2-proxy/oauth2-proxy/providers"
"gopkg.in/natefinch/lumberjack.v2"
Expand Down Expand Up @@ -91,20 +92,21 @@ type Options struct {

// These options allow for other providers besides Google, with
// potential overrides.
Provider string `flag:"provider" cfg:"provider" env:"OAUTH2_PROXY_PROVIDER"`
ProviderName string `flag:"provider-display-name" cfg:"provider_display_name" env:"OAUTH2_PROXY_PROVIDER_DISPLAY_NAME"`
OIDCIssuerURL string `flag:"oidc-issuer-url" cfg:"oidc_issuer_url" env:"OAUTH2_PROXY_OIDC_ISSUER_URL"`
InsecureOIDCAllowUnverifiedEmail bool `flag:"insecure-oidc-allow-unverified-email" cfg:"insecure_oidc_allow_unverified_email" env:"OAUTH2_PROXY_INSECURE_OIDC_ALLOW_UNVERIFIED_EMAIL"`
SkipOIDCDiscovery bool `flag:"skip-oidc-discovery" cfg:"skip_oidc_discovery" env:"OAUTH2_PROXY_SKIP_OIDC_DISCOVERY"`
OIDCJwksURL string `flag:"oidc-jwks-url" cfg:"oidc_jwks_url" env:"OAUTH2_PROXY_OIDC_JWKS_URL"`
LoginURL string `flag:"login-url" cfg:"login_url" env:"OAUTH2_PROXY_LOGIN_URL"`
RedeemURL string `flag:"redeem-url" cfg:"redeem_url" env:"OAUTH2_PROXY_REDEEM_URL"`
ProfileURL string `flag:"profile-url" cfg:"profile_url" env:"OAUTH2_PROXY_PROFILE_URL"`
ProtectedResource string `flag:"resource" cfg:"resource" env:"OAUTH2_PROXY_RESOURCE"`
ValidateURL string `flag:"validate-url" cfg:"validate_url" env:"OAUTH2_PROXY_VALIDATE_URL"`
Scope string `flag:"scope" cfg:"scope" env:"OAUTH2_PROXY_SCOPE"`
Prompt string `flag:"prompt" cfg:"prompt" env:"OAUTH2_PROXY_PROMPT"`
ApprovalPrompt string `flag:"approval-prompt" cfg:"approval_prompt" env:"OAUTH2_PROXY_APPROVAL_PROMPT"` // Deprecated by OIDC 1.0
Provider string `flag:"provider" cfg:"provider" env:"OAUTH2_PROXY_PROVIDER"`
ProviderName string `flag:"provider-display-name" cfg:"provider_display_name" env:"OAUTH2_PROXY_PROVIDER_DISPLAY_NAME"`
OIDCIssuerURL string `flag:"oidc-issuer-url" cfg:"oidc_issuer_url" env:"OAUTH2_PROXY_OIDC_ISSUER_URL"`
InsecureOIDCAllowUnverifiedEmail bool `flag:"insecure-oidc-allow-unverified-email" cfg:"insecure_oidc_allow_unverified_email" env:"OAUTH2_PROXY_INSECURE_OIDC_ALLOW_UNVERIFIED_EMAIL"`
InsecureOIDCSkipIssuerVerification bool `flag:"insecure-oidc-skip-issuer-verification" cfg:"insecure_oidc_skip_issuer_verification" env:"OAUTH2_PROXY_INSECURE_OIDC_SKIP_ISSUER_VERIFICATION"`
SkipOIDCDiscovery bool `flag:"skip-oidc-discovery" cfg:"skip_oidc_discovery" env:"OAUTH2_PROXY_SKIP_OIDC_DISCOVERY"`
OIDCJwksURL string `flag:"oidc-jwks-url" cfg:"oidc_jwks_url" env:"OAUTH2_PROXY_OIDC_JWKS_URL"`
LoginURL string `flag:"login-url" cfg:"login_url" env:"OAUTH2_PROXY_LOGIN_URL"`
RedeemURL string `flag:"redeem-url" cfg:"redeem_url" env:"OAUTH2_PROXY_REDEEM_URL"`
ProfileURL string `flag:"profile-url" cfg:"profile_url" env:"OAUTH2_PROXY_PROFILE_URL"`
ProtectedResource string `flag:"resource" cfg:"resource" env:"OAUTH2_PROXY_RESOURCE"`
ValidateURL string `flag:"validate-url" cfg:"validate_url" env:"OAUTH2_PROXY_VALIDATE_URL"`
Scope string `flag:"scope" cfg:"scope" env:"OAUTH2_PROXY_SCOPE"`
Prompt string `flag:"prompt" cfg:"prompt" env:"OAUTH2_PROXY_PROMPT"`
ApprovalPrompt string `flag:"approval-prompt" cfg:"approval_prompt" env:"OAUTH2_PROXY_APPROVAL_PROMPT"` // Deprecated by OIDC 1.0

// Configuration values for logging
LoggingFilename string `flag:"logging-filename" cfg:"logging_filename" env:"OAUTH2_PROXY_LOGGING_FILENAME"`
Expand Down Expand Up @@ -254,6 +256,44 @@ func (o *Options) Validate() error {

ctx := context.Background()

if o.InsecureOIDCSkipIssuerVerification && !o.SkipOIDCDiscovery {
// 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...")

if req, err := http.NewRequest("GET", strings.TrimSuffix(o.OIDCIssuerURL, "/")+"/.well-known/openid-configuration", nil); err == nil {
if body, err := requests.Request(req); err == nil {

// Prefer manually configured URLs. It's a bit unclear
// why you'd be doing discovery and also providing the URLs
// explicitly though...
if o.LoginURL == "" {
o.LoginURL = body.Get("authorization_endpoint").MustString()
}

if o.RedeemURL == "" {
o.RedeemURL = body.Get("token_endpoint").MustString()
}

if o.OIDCJwksURL == "" {
o.OIDCJwksURL = body.Get("jwks_uri").MustString()
}

if o.ProfileURL == "" {
o.ProfileURL = body.Get("userinfo_endpoint").MustString()
}

o.SkipOIDCDiscovery = true
} else {
logger.Printf("error: failed to discover OIDC configuration: %v", err)
}
} else {
logger.Printf("error: failed parsing OIDC discovery URL: %v", err)
}
}

// 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
Expand All @@ -270,7 +310,8 @@ func (o *Options) Validate() error {
}
keySet := oidc.NewRemoteKeySet(ctx, o.OIDCJwksURL)
o.oidcVerifier = oidc.NewVerifier(o.OIDCIssuerURL, keySet, &oidc.Config{
ClientID: o.ClientID,
ClientID: o.ClientID,
SkipIssuerCheck: o.InsecureOIDCSkipIssuerVerification,
})
} else {
// Configure discoverable provider data.
Expand All @@ -279,7 +320,8 @@ func (o *Options) Validate() error {
return err
}
o.oidcVerifier = provider.Verifier(&oidc.Config{
ClientID: o.ClientID,
ClientID: o.ClientID,
SkipIssuerCheck: o.InsecureOIDCSkipIssuerVerification,
})

o.LoginURL = provider.Endpoint().AuthURL
Expand Down