git.iko.soy/typeable/oauth2-proxy
on master help sign in
Add -skip-oidc-discovery option (#41)

* added karrieretutor go-oidc fork for using an AAD B2C Policy * added karrieretutor go-oidc fork for using an AAD B2C Policy * added --skip-oidc-discovery option * added --skip-oidc-discovery option * add simple test for skip-oidc-discovery option * revert Dockerfile to pusher upstream * revert Dockerfile to pusher upstream * remove karrieretutor b2c option leftover * remove karrieretutor b2c option leftover * Fix typo (missing letters) Co-Authored-By: marratj <marrat@marrat.de> * Fix typo (missing letters) Co-Authored-By: marratj <marrat@marrat.de> * replace fake http client with NewProvider() from go-oidc * remove OIDC UserInfo URL option (not required) * add info about -skip-oidc-discovery to README * add note to changelog * Update outdated comment

commit8816a2a972cf5c840ce87b7b331323781aee3ff1 authorMarcel D. Juhnke <marrat@marrat.de> dateMon 4 Mar 2019, 14:54 (8 years ago) parentfb1614c
5 files changed+78−9
CHANGELOG.md+1 README.md+22 main.go+2 options.go+36−9 options_test.go+17
CHANGELOG.md+1
@@ -3,6 +3,7 @@
33## Changes since v3.1.0
44
55- [#68](https://github.com/pusher/oauth2_proxy/pull/68) forward X-Auth-Access-Token header (@davidholsgrove)
6+- [#41](https://github.com/pusher/oauth2_proxy/pull/41) Added option to manually specify OIDC endpoints instead of relying on discovery
67
78# v3.1.0
89
README.md+22
@@ -166,6 +166,26 @@ OpenID Connect is a spec for OAUTH 2.0 + identity that is implemented by many ma
166166 -cookie-secure=false
167167 -email-domain example.com
168168
169+#### Skip OIDC discovery
170+
171+Some providers do not support OIDC discovery via their issuer URL, so oauth2_proxy cannot simply grab the authorization, token and jwks URI endpoints from the provider's metadata.
172+
173+In this case, you can set the `-skip-oidc-discovery` option, and supply those required endpoints manually:
174+
175+```
176+ -provider oidc
177+ -client-id oauth2_proxy
178+ -client-secret proxy
179+ -redirect-url http://127.0.0.1:4180/oauth2/callback
180+ -oidc-issuer-url http://127.0.0.1:5556
181+ -skip-oidc-discovery
182+ -login-url http://127.0.0.1:5556/authorize
183+ -redeem-url http://127.0.0.1:5556/token
184+ -oidc-jwks-url http://127.0.0.1:5556/keys
185+ -cookie-secure=false
186+ -email-domain example.com
187+```
188+
169189## Email Authentication
170190
171191To authorize by email domain use `--email-domain=yourcompany.com`. To authorize individual email addresses use `--authenticated-emails-file=/path/to/file` with one email per line. To authorize all email addresses use `--email-domain=*`.
@@ -213,6 +233,7 @@ Usage of oauth2_proxy:
213233 -https-address string: <addr>:<port> to listen on for HTTPS clients (default ":443")
214234 -login-url string: Authentication endpoint
215235 -oidc-issuer-url: the OpenID Connect issuer URL. ie: "https://accounts.google.com"
236+ -oidc-jwks-url string: OIDC JWKS URI for token verification; required if OIDC discovery is disabled
216237 -pass-access-token: pass OAuth access_token to upstream via X-Forwarded-Access-Token header
217238 -pass-authorization-header: pass OIDC IDToken to upstream via Authorization Bearer header
218239 -pass-basic-auth: pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream (default true)
@@ -232,6 +253,7 @@ Usage of oauth2_proxy:
232253 -signature-key string: GAP-Signature request signature key (algorithm:secretkey)
233254 -skip-auth-preflight: will skip authentication for OPTIONS requests
234255 -skip-auth-regex value: bypass authentication for requests path's that match (may be given multiple times)
256+ -skip-oidc-discovery: bypass OIDC endpoint discovery. login-url, redeem-url and oidc-jwks-url must be configured in this case
235257 -skip-provider-button: will skip sign-in-page to directly reach the next step: oauth/start
236258 -ssl-insecure-skip-verify: skip validation of certificates presented when using HTTPS
237259 -tls-cert string: path to certificate file
main.go+2
@@ -76,6 +76,8 @@ func main() {
7676
7777 flagSet.String("provider", "google", "OAuth provider")
7878 flagSet.String("oidc-issuer-url", "", "OpenID Connect issuer URL (ie: https://accounts.google.com)")
79+ flagSet.Bool("skip-oidc-discovery", false, "Skip OIDC discovery and use manually supplied Endpoints")
80+ flagSet.String("oidc-jwks-url", "", "OpenID Connect JWKS URL (ie: https://www.googleapis.com/oauth2/v3/certs)")
7981 flagSet.String("login-url", "", "Authentication endpoint")
8082 flagSet.String("redeem-url", "", "Token redemption endpoint")
8183 flagSet.String("profile-url", "", "Profile access endpoint")
options.go+36−9
@@ -71,6 +71,8 @@ type Options struct {
7171 // potential overrides.
7272 Provider string `flag:"provider" cfg:"provider"`
7373 OIDCIssuerURL string `flag:"oidc-issuer-url" cfg:"oidc_issuer_url"`
74+ SkipOIDCDiscovery bool `flag:"skip-oidc-discovery" cfg:"skip_oidc_discovery"`
75+ OIDCJwksURL string `flag:"oidc-jwks-url" cfg:"oidc_jwks_url"`
7476 LoginURL string `flag:"login-url" cfg:"login_url"`
7577 RedeemURL string `flag:"redeem-url" cfg:"redeem_url"`
7678 ProfileURL string `flag:"profile-url" cfg:"profile_url"`
@@ -121,6 +123,7 @@ func NewOptions() *Options {
121123 PassAuthorization: false,
122124 ApprovalPrompt: "force",
123125 RequestLogging: true,
126+ SkipOIDCDiscovery: false,
124127 RequestLoggingFormat: defaultRequestLoggingFormat,
125128 }
126129}
@@ -161,16 +164,40 @@ func (o *Options) Validate() error {
161164 }
162165
163166 if o.OIDCIssuerURL != "" {
164− // Configure discoverable provider data.
165− provider, err := oidc.NewProvider(context.Background(), o.OIDCIssuerURL)
166− if err != nil {
167− return err
167+
168+ ctx := context.Background()
169+
170+ // Construct a manual IDTokenVerifier from issuer URL & JWKS URI
171+ // instead of metadata discovery if we enable -skip-oidc-discovery.
172+ // In this case we need to make sure the required endpoints for
173+ // the provider are configured.
174+ if o.SkipOIDCDiscovery {
175+ if o.LoginURL == "" {
176+ msgs = append(msgs, "missing setting: login-url")
177+ }
178+ if o.RedeemURL == "" {
179+ msgs = append(msgs, "missing setting: redeem-url")
180+ }
181+ if o.OIDCJwksURL == "" {
182+ msgs = append(msgs, "missing setting: oidc-jwks-url")
183+ }
184+ keySet := oidc.NewRemoteKeySet(ctx, o.OIDCJwksURL)
185+ o.oidcVerifier = oidc.NewVerifier(o.OIDCIssuerURL, keySet, &oidc.Config{
186+ ClientID: o.ClientID,
187+ })
188+ } else {
189+ // Configure discoverable provider data.
190+ provider, err := oidc.NewProvider(ctx, o.OIDCIssuerURL)
191+ if err != nil {
192+ return err
193+ }
194+ o.oidcVerifier = provider.Verifier(&oidc.Config{
195+ ClientID: o.ClientID,
196+ })
197+
198+ o.LoginURL = provider.Endpoint().AuthURL
199+ o.RedeemURL = provider.Endpoint().TokenURL
168200 }
169− o.oidcVerifier = provider.Verifier(&oidc.Config{
170− ClientID: o.ClientID,
171− })
172− o.LoginURL = provider.Endpoint().AuthURL
173− o.RedeemURL = provider.Endpoint().TokenURL
174201 if o.Scope == "" {
175202 o.Scope = "openid email profile"
176203 }
options_test.go+17
@@ -251,3 +251,20 @@ func TestValidateCookieBadName(t *testing.T) {
251251 assert.Equal(t, err.Error(), "Invalid configuration:\n"+
252252 fmt.Sprintf(" invalid cookie name: %q", o.CookieName))
253253}
254+
255+func TestSkipOIDCDiscovery(t *testing.T) {
256+ o := testOptions()
257+ o.Provider = "oidc"
258+ o.OIDCIssuerURL = "https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/v2.0/"
259+ o.SkipOIDCDiscovery = true
260+
261+ err := o.Validate()
262+ assert.Equal(t, "Invalid configuration:\n"+
263+ fmt.Sprintf(" missing setting: login-url\n missing setting: redeem-url\n missing setting: oidc-jwks-url"), err.Error())
264+
265+ o.LoginURL = "https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_sign_in"
266+ o.RedeemURL = "https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/oauth2/v2.0/token?p=b2c_1_sign_in"
267+ o.OIDCJwksURL = "https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/discovery/v2.0/keys"
268+
269+ assert.Equal(t, nil, o.Validate())
270+}