mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2026-10-18 13:18:26 +02:00
Support for passing through URL query parameters from /oauth2/start to the ID provider's login URL.
You must explicitly configure oauth2-proxy (alpha config only) with which parameters are allowed to pass through, and optionally provide an allow-list of valid values and/or regular expressions for each one. Note that this mechanism subsumes the functionality of the "prompt", "approval_prompt" and "acr_values" legacy configuration options, which must be converted to the equivalent YAML when running in alpha config mode.
This commit is contained in:
@@ -632,10 +632,7 @@ func (l *LegacyProvider) convert() (Providers, error) {
|
||||
ProtectedResource: l.ProtectedResource,
|
||||
ValidateURL: l.ValidateURL,
|
||||
Scope: l.Scope,
|
||||
Prompt: l.Prompt,
|
||||
ApprovalPrompt: l.ApprovalPrompt,
|
||||
AllowedGroups: l.AllowedGroups,
|
||||
AcrValues: l.AcrValues,
|
||||
}
|
||||
|
||||
// This part is out of the switch section for all providers that support OIDC
|
||||
@@ -708,6 +705,24 @@ func (l *LegacyProvider) convert() (Providers, error) {
|
||||
provider.ID = l.ProviderType + "=" + l.ClientID
|
||||
}
|
||||
|
||||
// handle AcrValues, Prompt and ApprovalPrompt
|
||||
var urlParams []LoginURLParameter
|
||||
if l.AcrValues != "" {
|
||||
urlParams = append(urlParams, LoginURLParameter{Name: "acr_values", Default: []string{l.AcrValues}})
|
||||
}
|
||||
switch {
|
||||
case l.Prompt != "":
|
||||
urlParams = append(urlParams, LoginURLParameter{Name: "prompt", Default: []string{l.Prompt}})
|
||||
case l.ApprovalPrompt != "":
|
||||
urlParams = append(urlParams, LoginURLParameter{Name: "approval_prompt", Default: []string{l.ApprovalPrompt}})
|
||||
default:
|
||||
// match legacy behaviour by default - if neither prompt nor approval_prompt
|
||||
// specified, use approval_prompt=force
|
||||
urlParams = append(urlParams, LoginURLParameter{Name: "approval_prompt", Default: []string{"force"}})
|
||||
}
|
||||
|
||||
provider.LoginURLParameters = urlParams
|
||||
|
||||
providers = append(providers, provider)
|
||||
|
||||
return providers, nil
|
||||
|
||||
@@ -118,6 +118,9 @@ var _ = Describe("Legacy Options", func() {
|
||||
opts.Providers[0].OIDCConfig.InsecureSkipNonce = true
|
||||
opts.Providers[0].OIDCConfig.AudienceClaims = []string{"aud"}
|
||||
opts.Providers[0].OIDCConfig.ExtraAudiences = []string{}
|
||||
opts.Providers[0].LoginURLParameters = []LoginURLParameter{
|
||||
{Name: "approval_prompt", Default: []string{"force"}},
|
||||
}
|
||||
|
||||
converted, err := legacyOpts.ToOptions()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
@@ -891,21 +894,41 @@ var _ = Describe("Legacy Options", func() {
|
||||
// Non defaults for these options
|
||||
clientID := "abcd"
|
||||
|
||||
defaultURLParams := []LoginURLParameter{
|
||||
{Name: "approval_prompt", Default: []string{"force"}},
|
||||
}
|
||||
|
||||
defaultProvider := Provider{
|
||||
ID: "google=" + clientID,
|
||||
ClientID: clientID,
|
||||
Type: "google",
|
||||
ID: "google=" + clientID,
|
||||
ClientID: clientID,
|
||||
Type: "google",
|
||||
LoginURLParameters: defaultURLParams,
|
||||
}
|
||||
defaultLegacyProvider := LegacyProvider{
|
||||
ClientID: clientID,
|
||||
ProviderType: "google",
|
||||
}
|
||||
|
||||
displayNameProvider := Provider{
|
||||
ID: "displayName",
|
||||
Name: "displayName",
|
||||
defaultProviderWithPrompt := Provider{
|
||||
ID: "google=" + clientID,
|
||||
ClientID: clientID,
|
||||
Type: "google",
|
||||
LoginURLParameters: []LoginURLParameter{
|
||||
{Name: "prompt", Default: []string{"switch_user"}},
|
||||
},
|
||||
}
|
||||
defaultLegacyProviderWithPrompt := LegacyProvider{
|
||||
ClientID: clientID,
|
||||
ProviderType: "google",
|
||||
Prompt: "switch_user",
|
||||
}
|
||||
|
||||
displayNameProvider := Provider{
|
||||
ID: "displayName",
|
||||
Name: "displayName",
|
||||
ClientID: clientID,
|
||||
Type: "google",
|
||||
LoginURLParameters: defaultURLParams,
|
||||
}
|
||||
|
||||
displayNameLegacyProvider := LegacyProvider{
|
||||
@@ -923,6 +946,7 @@ var _ = Describe("Legacy Options", func() {
|
||||
ServiceAccountJSON: "test.json",
|
||||
Groups: []string{"1", "2"},
|
||||
},
|
||||
LoginURLParameters: defaultURLParams,
|
||||
}
|
||||
|
||||
internalConfigLegacyProvider := LegacyProvider{
|
||||
@@ -950,6 +974,11 @@ var _ = Describe("Legacy Options", func() {
|
||||
expectedProviders: Providers{defaultProvider},
|
||||
errMsg: "",
|
||||
}),
|
||||
Entry("with prompt setting", &convertProvidersTableInput{
|
||||
legacyProvider: defaultLegacyProviderWithPrompt,
|
||||
expectedProviders: Providers{defaultProviderWithPrompt},
|
||||
errMsg: "",
|
||||
}),
|
||||
Entry("with provider display name", &convertProvidersTableInput{
|
||||
legacyProvider: displayNameLegacyProvider,
|
||||
expectedProviders: Providers{displayNameProvider},
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package options
|
||||
|
||||
// LoginURLParameter is the configuration for a single query parameter that
|
||||
// can be passed through from the `/oauth2/start` endpoint to the IdP login
|
||||
// URL. The "default" option specifies the default value or values (if any)
|
||||
// that will be passed to the IdP for this parameter, and "allow" is a list
|
||||
// of options for ways in which this parameter can be set or overridden via
|
||||
// the query string to `/oauth2/start`.
|
||||
// If _only_ a default is specified and no "allow" then the parameter is
|
||||
// effectively fixed - the default value will always be used and anything
|
||||
// passed to the start URL will be ignored. If _only_ "allow" is specified
|
||||
// but no default then the parameter will only be passed on to the IdP if
|
||||
// the caller provides it, and no value will be sent otherwise.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// A parameter whose value is fixed
|
||||
//
|
||||
// ```
|
||||
// name: organization
|
||||
// default:
|
||||
// - myorg
|
||||
// ```
|
||||
//
|
||||
// A parameter that is not passed by default, but may be set to one of a
|
||||
// fixed set of values
|
||||
//
|
||||
// ```
|
||||
// name: prompt
|
||||
// allow:
|
||||
// - value: login
|
||||
// - value: consent
|
||||
// - value: select_account
|
||||
// ```
|
||||
//
|
||||
// A parameter that is passed by default but may be overridden by one of
|
||||
// a fixed set of values
|
||||
//
|
||||
// ```
|
||||
// name: prompt
|
||||
// default: ["login"]
|
||||
// allow:
|
||||
// - value: consent
|
||||
// - value: select_account
|
||||
// ```
|
||||
//
|
||||
// A parameter that may be overridden, but only by values that match a
|
||||
// regular expression. For example to restrict `login_hint` to email
|
||||
// addresses in your organization's domain:
|
||||
//
|
||||
// ```
|
||||
// name: login_hint
|
||||
// allow:
|
||||
// - pattern: '^[^@]*@example\.com$'
|
||||
// # this allows at most one "@" sign, and requires "example.com" domain.
|
||||
// ```
|
||||
//
|
||||
// Note that the YAML rules around exactly which characters are allowed
|
||||
// and/or require escaping in different types of string literals are
|
||||
// convoluted. For regular expressions the single quoted form is simplest
|
||||
// as backslash is not considered to be an escape character. Alternatively
|
||||
// use the "chomped block" format `|-`:
|
||||
//
|
||||
// ```
|
||||
// - pattern: |-
|
||||
// ^[^@]*@example\.com$
|
||||
// ```
|
||||
//
|
||||
// The hyphen is important, a `|` block would have a trailing newline
|
||||
// character.
|
||||
type LoginURLParameter struct {
|
||||
// Name specifies the name of the query parameter.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Default specifies a default value or values that will be
|
||||
// passed to the IdP if not overridden.
|
||||
//+optional
|
||||
Default []string `json:"default,omitempty"`
|
||||
|
||||
// Allow specifies rules about how the default (if any) may be
|
||||
// overridden via the query string to `/oauth2/start`. Only
|
||||
// values that match one or more of the allow rules will be
|
||||
// forwarded to the IdP.
|
||||
//+optional
|
||||
Allow []URLParameterRule `json:"allow,omitempty"`
|
||||
}
|
||||
|
||||
// URLParameterRule represents a rule by which query parameters
|
||||
// passed to the `/oauth2/start` endpoint are checked to determine whether
|
||||
// they are valid overrides for the given parameter passed to the IdP's
|
||||
// login URL. Either Value or Pattern should be supplied, not both.
|
||||
type URLParameterRule struct {
|
||||
// A Value rule matches just this specific value
|
||||
Value *string `json:"value,omitempty"`
|
||||
|
||||
// A Pattern rule gives a regular expression that must be matched by
|
||||
// some substring of the value. The expression is _not_ automatically
|
||||
// anchored to the start and end of the value, if you _want_ to restrict
|
||||
// the whole parameter value you must anchor it yourself with `^` and `$`.
|
||||
Pattern *string `json:"pattern,omitempty"`
|
||||
}
|
||||
@@ -62,6 +62,8 @@ type Provider struct {
|
||||
|
||||
// LoginURL is the authentication endpoint
|
||||
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"`
|
||||
// RedeemURL is the token redemption endpoint
|
||||
RedeemURL string `json:"redeemURL,omitempty"`
|
||||
// ProfileURL is the profile access endpoint
|
||||
@@ -72,16 +74,8 @@ type Provider struct {
|
||||
ValidateURL string `json:"validateURL,omitempty"`
|
||||
// Scope is the OAuth scope specification
|
||||
Scope string `json:"scope,omitempty"`
|
||||
// Prompt is OIDC prompt
|
||||
Prompt string `json:"prompt,omitempty"`
|
||||
// ApprovalPrompt is the OAuth approval_prompt
|
||||
// default is set to 'force'
|
||||
ApprovalPrompt string `json:"approvalPrompt,omitempty"`
|
||||
// AllowedGroups is a list of restrict logins to members of this group
|
||||
AllowedGroups []string `json:"allowedGroups,omitempty"`
|
||||
|
||||
// AcrValues is a string of acr values
|
||||
AcrValues string `json:"acrValues,omitempty"`
|
||||
}
|
||||
|
||||
// ProviderType is used to enumerate the different provider type options
|
||||
@@ -243,9 +237,7 @@ type LoginGovOptions struct {
|
||||
func providerDefaults() Providers {
|
||||
providers := Providers{
|
||||
{
|
||||
Type: "google",
|
||||
Prompt: "", // Change to "login" when ApprovalPrompt officially deprecated
|
||||
ApprovalPrompt: "force",
|
||||
Type: "google",
|
||||
AzureConfig: AzureOptions{
|
||||
Tenant: "common",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user