Skip to content

Commit

Permalink
filters/auth: allow insecure grant flow (#2457)
Browse files Browse the repository at this point in the history
Add a flag to allow insecure grant flow:
* issue token cookie without secure attribute
* use http schem for callback url

Signed-off-by: Alexander Yastrebov <[email protected]>
  • Loading branch information
AlexanderYastrebov authored Jul 17, 2023
1 parent d6da18a commit 62302e4
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 3 deletions.
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ type Config struct {
Oauth2GrantTokeninfoKeys *listFlag `yaml:"oauth2-grant-tokeninfo-keys"`
Oauth2TokenCookieName string `yaml:"oauth2-token-cookie-name"`
Oauth2TokenCookieRemoveSubdomains int `yaml:"oauth2-token-cookie-remove-subdomains"`
Oauth2GrantInsecure bool `yaml:"oauth2-grant-insecure"`
WebhookTimeout time.Duration `yaml:"webhook-timeout"`
OidcSecretsFile string `yaml:"oidc-secrets-file"`
OIDCCookieValidity time.Duration `yaml:"oidc-cookie-validity"`
Expand Down Expand Up @@ -475,6 +476,7 @@ func NewConfig() *Config {
flag.Var(cfg.Oauth2GrantTokeninfoKeys, "oauth2-grant-tokeninfo-keys", "non-empty comma separated list configures keys to preserve in OAuth2 Grant Flow tokeninfo")
flag.StringVar(&cfg.Oauth2TokenCookieName, "oauth2-token-cookie-name", "oauth2-grant", "sets the name of the cookie where the encrypted token is stored")
flag.IntVar(&cfg.Oauth2TokenCookieRemoveSubdomains, "oauth2-token-cookie-remove-subdomains", 1, "sets the number of subdomains to remove from the callback request hostname to obtain token cookie domain")
flag.BoolVar(&cfg.Oauth2GrantInsecure, "oauth2-grant-insecure", false, "omits Secure attribute of the token cookie and uses http scheme for callback url")
flag.DurationVar(&cfg.WebhookTimeout, "webhook-timeout", 2*time.Second, "sets the webhook request timeout duration")
flag.StringVar(&cfg.OidcSecretsFile, "oidc-secrets-file", "", "file storing the encryption key of the OID Connect token. Enables OIDC filters")
flag.DurationVar(&cfg.OIDCCookieValidity, "oidc-cookie-validity", time.Hour, "sets the cookie expiry time to +1h for OIDC filters, in case no 'exp' claim is found in the JWT token")
Expand Down Expand Up @@ -818,6 +820,7 @@ func (c *Config) ToOptions() skipper.Options {
OAuth2GrantTokeninfoKeys: c.Oauth2GrantTokeninfoKeys.values,
OAuth2TokenCookieName: c.Oauth2TokenCookieName,
OAuth2TokenCookieRemoveSubdomains: c.Oauth2TokenCookieRemoveSubdomains,
OAuth2GrantInsecure: c.Oauth2GrantInsecure,
WebhookTimeout: c.WebhookTimeout,
OIDCSecretsFile: c.OidcSecretsFile,
OIDCCookieValidity: c.OIDCCookieValidity,
Expand Down
35 changes: 35 additions & 0 deletions filters/auth/grant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1020,3 +1020,38 @@ func TestGrantCredentialsPlaceholder(t *testing.T) {
checkStatus(t, rsp, http.StatusForbidden)
})
}

func TestGrantInsecure(t *testing.T) {
provider := newGrantTestAuthServer(testToken, testAccessCode)
defer provider.Close()

tokeninfo := newGrantTestTokeninfo(testToken, "")
defer tokeninfo.Close()

config := newGrantTestConfig(tokeninfo.URL, provider.URL)
config.Insecure = true

proxy, client := newSimpleGrantAuthProxy(t, config)
defer proxy.Close()

rsp, err := client.Get(proxy.URL + "/test")
require.NoError(t, err)
defer rsp.Body.Close()

rsp, err = client.Get(rsp.Header.Get("Location"))
require.NoError(t, err, "Failed to make request to provider")
defer rsp.Body.Close()

callbackUrl := rsp.Header.Get("Location")

assert.True(t, strings.HasPrefix(callbackUrl, "http://"), "Callback URL should be insecure")

rsp, err = client.Get(callbackUrl)
require.NoError(t, err, "Failed to make callback request to proxy")
defer rsp.Body.Close()

c, ok := findAuthCookie(rsp)
require.True(t, ok, "Cookie not found")

assert.False(t, c.Secure, "Cookie should be insecure")
}
10 changes: 9 additions & 1 deletion filters/auth/grantconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ type OAuthConfig struct {
// Init converts default nil to 1.
TokenCookieRemoveSubdomains *int

// Insecure omits Secure attribute of the token cookie and uses http scheme for callback url.
Insecure bool

// ConnectionTimeout used for tokeninfo, access-token and refresh-token endpoint.
ConnectionTimeout time.Duration

Expand Down Expand Up @@ -341,7 +344,12 @@ func (c *OAuthConfig) GetAuthURLParameters(redirectURI string) []oauth2.AuthCode
func (c *OAuthConfig) RedirectURLs(req *http.Request) (redirect, original string) {
u := *req.URL

u.Scheme = "https"
if c.Insecure {
u.Scheme = "http"
} else {
u.Scheme = "https"
}

u.Host = req.Host

original = u.String()
Expand Down
4 changes: 2 additions & 2 deletions filters/auth/grantcookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func createDeleteCookie(config *OAuthConfig, host string) *http.Cookie {
Path: "/",
Domain: extractDomainFromHost(host, *config.TokenCookieRemoveSubdomains),
MaxAge: -1,
Secure: true,
Secure: !config.Insecure,
HttpOnly: true,
}
}
Expand Down Expand Up @@ -133,7 +133,7 @@ func createCookie(config *OAuthConfig, host string, t *oauth2.Token) (*http.Cook
Path: "/",
Domain: domain,
Expires: t.Expiry.Add(time.Hour * 24 * 30),
Secure: true,
Secure: !config.Insecure,
HttpOnly: true,
}, nil
}
4 changes: 4 additions & 0 deletions skipper.go
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,9 @@ type Options struct {
// the callback request hostname to obtain token cookie domain.
OAuth2TokenCookieRemoveSubdomains int

// OAuth2GrantInsecure omits Secure attribute of the token cookie and uses http scheme for callback url.
OAuth2GrantInsecure bool

// CompressEncodings, if not empty replace default compression encodings
CompressEncodings []string

Expand Down Expand Up @@ -1724,6 +1727,7 @@ func run(o Options, sig chan os.Signal, idleConnsCH chan struct{}) error {
oauthConfig.GrantTokeninfoKeys = o.OAuth2GrantTokeninfoKeys
oauthConfig.TokenCookieName = o.OAuth2TokenCookieName
oauthConfig.TokenCookieRemoveSubdomains = &o.OAuth2TokenCookieRemoveSubdomains
oauthConfig.Insecure = o.OAuth2GrantInsecure
oauthConfig.ConnectionTimeout = o.OAuthTokeninfoTimeout
oauthConfig.MaxIdleConnectionsPerHost = o.IdleConnectionsPerHost
oauthConfig.Tracer = tracer
Expand Down

0 comments on commit 62302e4

Please sign in to comment.