git.iko.soy/typeable/oauth2-proxy
on master help sign in
feat: allow to set non-default authorization request response mode (#3001)

* Update Go version in devcontainer * Add option to change response mode in authorization request * Fix option name * Update docs and changelog * Rename config value to underscore * Add unit tests for added parameter * Move change to upcoming release * Generate alpha config --------- Co-authored-by: Michael Cornel <michael@stieler.it>

commitf6b95c0df85ab114059e66ffb7d6f2bdb8b2d5ec authorMichael Cornel <michael@stieler.it> dateMon 31 Mar 2025, 10:04 (2 years ago) parentb34b617
10 files changed+49−5
.devcontainer/Dockerfile+1−1 CHANGELOG.md+2 docs/docs/configuration/alpha_config.md+1 docs/docs/configuration/overview.md+1 pkg/apis/options/legacy_options.go+3 pkg/apis/options/providers.go+2 providers/provider_data.go+2 providers/provider_default.go+5 providers/provider_default_test.go+27 providers/providers.go+5−4
.devcontainer/Dockerfile+1−1
@@ -1,4 +1,4 @@
1−FROM mcr.microsoft.com/vscode/devcontainers/go:1-1.22
1+FROM mcr.microsoft.com/vscode/devcontainers/go:1-1.23
22
33SHELL ["/bin/bash", "-o", "pipefail", "-c"]
44
CHANGELOG.md+2
@@ -8,6 +8,8 @@
88
99## Changes since v7.8.2
1010
11+- [#3001](https://github.com/oauth2-proxy/oauth2-proxy/pull/3001) Allow to set non-default authorization request response mode (@stieler-it)
12+
1113# V7.8.2
1214
1315## Release Highlights
docs/docs/configuration/alpha_config.md+1
@@ -445,6 +445,7 @@ Provider holds all configuration for a single provider
445445| `useSystemTrustStore` | _bool_ | UseSystemTrustStore determines if your custom CA files and the system trust store are used<br/>If set to true, your custom CA files and the system trust store are used otherwise only your custom CA files. |
446446| `loginURL` | _string_ | LoginURL is the authentication endpoint |
447447| `loginURLParameters` | _[[]LoginURLParameter](#loginurlparameter)_ | LoginURLParameters defines the parameters that can be passed from the start URL to the IdP login URL |
448+| `authRequestResponseMode` | _string_ | AuthRequestResponseMode defines the response mode to request during authorization request |
448449| `redeemURL` | _string_ | RedeemURL is the token redemption endpoint |
449450| `profileURL` | _string_ | ProfileURL is the profile access endpoint |
450451| `skipClaimsFromProfileURL` | _bool_ | SkipClaimsFromProfileURL allows to skip request to Profile URL for resolving claims not present in id_token<br/>default set to 'false' |
docs/docs/configuration/overview.md+1
@@ -91,6 +91,7 @@ Provider specific options can be found on their respective subpages.
9191| flag: `--jwt-key-file`<br/>toml: `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 | |
9292| flag: `--jwt-key`<br/>toml: `jwt_key` | string | private key in PEM format used to sign JWT, so that you can say something like `--jwt-key="${OAUTH2_PROXY_JWT_KEY}"`: required by login.gov | |
9393| flag: `--login-url`<br/>toml: `login_url` | string | Authentication endpoint | |
94+| flag: `--auth-request-response-mode`<br/>toml: `auth-request-response-mode` | string | Response mode to ask for during authentication request | |
9495| flag: `--oidc-audience-claim`<br/>toml: `oidc_audience_claims` | string | which OIDC claim contains the audience | `"aud"` |
9596| flag: `--oidc-email-claim`<br/>toml: `oidc_email_claim` | string | which OIDC claim contains the user's email | `"email"` |
9697| flag: `--oidc-extra-audience`<br/>toml: `oidc_extra_audiences` | string \| list | additional audiences which are allowed to pass verification | `"[]"` |
pkg/apis/options/legacy_options.go+3
@@ -524,6 +524,7 @@ type LegacyProvider struct {
524524 OIDCExtraAudiences []string `flag:"oidc-extra-audience" cfg:"oidc_extra_audiences"`
525525 OIDCPublicKeyFiles []string `flag:"oidc-public-key-file" cfg:"oidc_public_key_files"`
526526 LoginURL string `flag:"login-url" cfg:"login_url"`
527+ AuthRequestResponseMode string `flag:"auth-request-response-mode" cfg:"auth_request_response_mode"`
527528 RedeemURL string `flag:"redeem-url" cfg:"redeem_url"`
528529 ProfileURL string `flag:"profile-url" cfg:"profile_url"`
529530 SkipClaimsFromProfileURL bool `flag:"skip-claims-from-profile-url" cfg:"skip_claims_from_profile_url"`
@@ -586,6 +587,7 @@ func legacyProviderFlagSet() *pflag.FlagSet {
586587 flagSet.String("login-url", "", "Authentication endpoint")
587588 flagSet.String("redeem-url", "", "Token redemption endpoint")
588589 flagSet.String("profile-url", "", "Profile access endpoint")
590+ flagSet.String("auth-request-response-mode", "", "Authorization request response mode")
589591 flagSet.Bool("skip-claims-from-profile-url", false, "Skip loading missing claims from profile URL")
590592 flagSet.String("resource", "", "The resource that is protected (Azure AD only)")
591593 flagSet.String("validate-url", "", "Access token validation endpoint")
@@ -684,6 +686,7 @@ func (l *LegacyProvider) convert() (Providers, error) {
684686 AllowedGroups: l.AllowedGroups,
685687 CodeChallengeMethod: l.CodeChallengeMethod,
686688 BackendLogoutURL: l.BackendLogoutURL,
689+ AuthRequestResponseMode: l.AuthRequestResponseMode,
687690 }
688691
689692 // This part is out of the switch section for all providers that support OIDC
pkg/apis/options/providers.go+2
@@ -68,6 +68,8 @@ type Provider struct {
6868 LoginURL string `json:"loginURL,omitempty"`
6969 // LoginURLParameters defines the parameters that can be passed from the start URL to the IdP login URL
7070 LoginURLParameters []LoginURLParameter `json:"loginURLParameters,omitempty"`
71+ // AuthRequestResponseMode defines the response mode to request during authorization request
72+ AuthRequestResponseMode string `json:"authRequestResponseMode,omitempty"`
7173 // RedeemURL is the token redemption endpoint
7274 RedeemURL string `json:"redeemURL,omitempty"`
7375 // ProfileURL is the profile access endpoint
providers/provider_data.go+2
@@ -37,6 +37,8 @@ type ProviderData struct {
3737 ClientSecret string
3838 ClientSecretFile string
3939 Scope string
40+ // The response mode requested from the provider or empty for default ("query")
41+ AuthRequestResponseMode string
4042 // The picked CodeChallenge Method or empty if none.
4143 CodeChallengeMethod string
4244 // Code challenge methods supported by the Provider
providers/provider_default.go+5
@@ -36,6 +36,11 @@ var (
3636// codeChallenge and codeChallengeMethod are the PKCE challenge and method to append to the URL params.
3737// they will be empty strings if no code challenge should be presented
3838func (p *ProviderData) GetLoginURL(redirectURI, state, _ string, extraParams url.Values) string {
39+ // Response mode should only be set if a non default mode is requested
40+ if p.AuthRequestResponseMode != "" {
41+ extraParams.Add("response_mode", p.AuthRequestResponseMode)
42+ }
43+
3944 loginURL := makeLoginURL(p, redirectURI, state, extraParams)
4045 return loginURL.String()
4146}
providers/provider_default_test.go+27
@@ -119,3 +119,30 @@ func TestProviderDataAuthorize(t *testing.T) {
119119 })
120120 }
121121}
122+
123+func TestResponseModeConfigured(t *testing.T) {
124+ p := &ProviderData{
125+ LoginURL: &url.URL{
126+ Scheme: "http",
127+ Host: "my.test.idp",
128+ Path: "/oauth/authorize",
129+ },
130+ AuthRequestResponseMode: "form_post",
131+ }
132+
133+ result := p.GetLoginURL("https://my.test.app/oauth", "", "", url.Values{})
134+ assert.Contains(t, result, "response_mode=form_post")
135+}
136+
137+func TestResponseModeNotConfigured(t *testing.T) {
138+ p := &ProviderData{
139+ LoginURL: &url.URL{
140+ Scheme: "http",
141+ Host: "my.test.idp",
142+ Path: "/oauth/authorize",
143+ },
144+ }
145+
146+ result := p.GetLoginURL("https://my.test.app/oauth", "", "", url.Values{})
147+ assert.NotContains(t, result, "response_mode")
148+}
providers/providers.go+5−4
@@ -74,10 +74,11 @@ func NewProvider(providerConfig options.Provider) (Provider, error) {
7474
7575func newProviderDataFromConfig(providerConfig options.Provider) (*ProviderData, error) {
7676 p := &ProviderData{
77− Scope: providerConfig.Scope,
78− ClientID: providerConfig.ClientID,
79− ClientSecret: providerConfig.ClientSecret,
80− ClientSecretFile: providerConfig.ClientSecretFile,
77+ Scope: providerConfig.Scope,
78+ ClientID: providerConfig.ClientID,
79+ ClientSecret: providerConfig.ClientSecret,
80+ ClientSecretFile: providerConfig.ClientSecretFile,
81+ AuthRequestResponseMode: providerConfig.AuthRequestResponseMode,
8182 }
8283
8384 needsVerifier, err := providerRequiresOIDCProviderVerifier(providerConfig.Type)