1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-07-15 01:44:22 +02:00

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>
This commit is contained in:
Michael Cornel
2025-03-31 10:04:19 +02:00
committed by GitHub
parent b34b617aad
commit f6b95c0df8
10 changed files with 49 additions and 5 deletions

View File

@ -1,4 +1,4 @@
FROM mcr.microsoft.com/vscode/devcontainers/go:1-1.22
FROM mcr.microsoft.com/vscode/devcontainers/go:1-1.23
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

View File

@ -8,6 +8,8 @@
## Changes since v7.8.2
- [#3001](https://github.com/oauth2-proxy/oauth2-proxy/pull/3001) Allow to set non-default authorization request response mode (@stieler-it)
# V7.8.2
## Release Highlights

View File

@ -445,6 +445,7 @@ Provider holds all configuration for a single provider
| `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. |
| `loginURL` | _string_ | LoginURL is the authentication endpoint |
| `loginURLParameters` | _[[]LoginURLParameter](#loginurlparameter)_ | LoginURLParameters defines the parameters that can be passed from the start URL to the IdP login URL |
| `authRequestResponseMode` | _string_ | AuthRequestResponseMode defines the response mode to request during authorization request |
| `redeemURL` | _string_ | RedeemURL is the token redemption endpoint |
| `profileURL` | _string_ | ProfileURL is the profile access endpoint |
| `skipClaimsFromProfileURL` | _bool_ | SkipClaimsFromProfileURL allows to skip request to Profile URL for resolving claims not present in id_token<br/>default set to 'false' |

View File

@ -91,6 +91,7 @@ Provider specific options can be found on their respective subpages.
| 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 | |
| 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 | |
| flag: `--login-url`<br/>toml: `login_url` | string | Authentication endpoint | |
| flag: `--auth-request-response-mode`<br/>toml: `auth-request-response-mode` | string | Response mode to ask for during authentication request | |
| flag: `--oidc-audience-claim`<br/>toml: `oidc_audience_claims` | string | which OIDC claim contains the audience | `"aud"` |
| flag: `--oidc-email-claim`<br/>toml: `oidc_email_claim` | string | which OIDC claim contains the user's email | `"email"` |
| flag: `--oidc-extra-audience`<br/>toml: `oidc_extra_audiences` | string \| list | additional audiences which are allowed to pass verification | `"[]"` |

View File

@ -524,6 +524,7 @@ type LegacyProvider struct {
OIDCExtraAudiences []string `flag:"oidc-extra-audience" cfg:"oidc_extra_audiences"`
OIDCPublicKeyFiles []string `flag:"oidc-public-key-file" cfg:"oidc_public_key_files"`
LoginURL string `flag:"login-url" cfg:"login_url"`
AuthRequestResponseMode string `flag:"auth-request-response-mode" cfg:"auth_request_response_mode"`
RedeemURL string `flag:"redeem-url" cfg:"redeem_url"`
ProfileURL string `flag:"profile-url" cfg:"profile_url"`
SkipClaimsFromProfileURL bool `flag:"skip-claims-from-profile-url" cfg:"skip_claims_from_profile_url"`
@ -586,6 +587,7 @@ func legacyProviderFlagSet() *pflag.FlagSet {
flagSet.String("login-url", "", "Authentication endpoint")
flagSet.String("redeem-url", "", "Token redemption endpoint")
flagSet.String("profile-url", "", "Profile access endpoint")
flagSet.String("auth-request-response-mode", "", "Authorization request response mode")
flagSet.Bool("skip-claims-from-profile-url", false, "Skip loading missing claims from profile URL")
flagSet.String("resource", "", "The resource that is protected (Azure AD only)")
flagSet.String("validate-url", "", "Access token validation endpoint")
@ -684,6 +686,7 @@ func (l *LegacyProvider) convert() (Providers, error) {
AllowedGroups: l.AllowedGroups,
CodeChallengeMethod: l.CodeChallengeMethod,
BackendLogoutURL: l.BackendLogoutURL,
AuthRequestResponseMode: l.AuthRequestResponseMode,
}
// This part is out of the switch section for all providers that support OIDC

View File

@ -68,6 +68,8 @@ type Provider struct {
LoginURL string `json:"loginURL,omitempty"`
// LoginURLParameters defines the parameters that can be passed from the start URL to the IdP login URL
LoginURLParameters []LoginURLParameter `json:"loginURLParameters,omitempty"`
// AuthRequestResponseMode defines the response mode to request during authorization request
AuthRequestResponseMode string `json:"authRequestResponseMode,omitempty"`
// RedeemURL is the token redemption endpoint
RedeemURL string `json:"redeemURL,omitempty"`
// ProfileURL is the profile access endpoint

View File

@ -37,6 +37,8 @@ type ProviderData struct {
ClientSecret string
ClientSecretFile string
Scope string
// The response mode requested from the provider or empty for default ("query")
AuthRequestResponseMode string
// The picked CodeChallenge Method or empty if none.
CodeChallengeMethod string
// Code challenge methods supported by the Provider

View File

@ -36,6 +36,11 @@ var (
// codeChallenge and codeChallengeMethod are the PKCE challenge and method to append to the URL params.
// they will be empty strings if no code challenge should be presented
func (p *ProviderData) GetLoginURL(redirectURI, state, _ string, extraParams url.Values) string {
// Response mode should only be set if a non default mode is requested
if p.AuthRequestResponseMode != "" {
extraParams.Add("response_mode", p.AuthRequestResponseMode)
}
loginURL := makeLoginURL(p, redirectURI, state, extraParams)
return loginURL.String()
}

View File

@ -119,3 +119,30 @@ func TestProviderDataAuthorize(t *testing.T) {
})
}
}
func TestResponseModeConfigured(t *testing.T) {
p := &ProviderData{
LoginURL: &url.URL{
Scheme: "http",
Host: "my.test.idp",
Path: "/oauth/authorize",
},
AuthRequestResponseMode: "form_post",
}
result := p.GetLoginURL("https://my.test.app/oauth", "", "", url.Values{})
assert.Contains(t, result, "response_mode=form_post")
}
func TestResponseModeNotConfigured(t *testing.T) {
p := &ProviderData{
LoginURL: &url.URL{
Scheme: "http",
Host: "my.test.idp",
Path: "/oauth/authorize",
},
}
result := p.GetLoginURL("https://my.test.app/oauth", "", "", url.Values{})
assert.NotContains(t, result, "response_mode")
}

View File

@ -74,10 +74,11 @@ func NewProvider(providerConfig options.Provider) (Provider, error) {
func newProviderDataFromConfig(providerConfig options.Provider) (*ProviderData, error) {
p := &ProviderData{
Scope: providerConfig.Scope,
ClientID: providerConfig.ClientID,
ClientSecret: providerConfig.ClientSecret,
ClientSecretFile: providerConfig.ClientSecretFile,
Scope: providerConfig.Scope,
ClientID: providerConfig.ClientID,
ClientSecret: providerConfig.ClientSecret,
ClientSecretFile: providerConfig.ClientSecretFile,
AuthRequestResponseMode: providerConfig.AuthRequestResponseMode,
}
needsVerifier, err := providerRequiresOIDCProviderVerifier(providerConfig.Type)