-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support HTTP method based allowlists #789
Conversation
Leaving this in draft form for now. I mostly shifted parts we wanted to keep from the I want to convert the new |
oauthproxy.go
Outdated
// buildRoutesAllowlist builds a []route from either the legacy SkipAuthRegex | ||
// option (paths only support) or newer SkipAuthRoutes option (method=path | ||
// support) | ||
func buildRoutesAllowlist(opts *options.Options) ([]*allowedRoute, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved configuration out of the options validation (to further the goal of that purely validating and doing no setup).
I know this isn't the best spot, but it gets it with the other very related configuration builders in this file that will eventually be refactored together in another PR to a better spot.
@@ -78,12 +77,19 @@ func TestClientSecretFileOption(t *testing.T) { | |||
if err != nil { | |||
t.Fatalf("failed to create temp file: %v", err) | |||
} | |||
f.WriteString("testcase") | |||
_, err = f.WriteString("testcase") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why my IDE catches these when I try to commit but GoSec doesn't 🤷♂️
These are unrelated to this PR, just handling errors that could be thrown.
7dcbe78
to
e2d198d
Compare
@@ -1482,28 +1482,28 @@ func TestAuthOnlyEndpointSetBasicAuthFalseRequestHeaders(t *testing.T) { | |||
} | |||
|
|||
func TestAuthSkippedForPreflightRequests(t *testing.T) { | |||
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming conflict with imported upstream package -- This is unrelated cleanup that I was warned about when I attempted to commit.
9371bad
to
4b5cf8c
Compare
oauthproxy.go
Outdated
path string | ||
) | ||
|
||
parts := strings.Split(methodPath, "=") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's 1 case where this logic won't be fully backwards compatible with migrating former --skip-auth-regex
entries to this without a method:
Regexes with a =
in it (e.g querystring) so /my/path\?q=data
will view /my/path\?q
as the HTTP method to allow and data
as the path regex.
The hack for this scenario is =/my/path\?q=data
. Just isn't graceful. Forcing a regex wrapper (E.g. /regex/
or #regex#
etc) would work? But would make the migration harder for 99% of use cases.
I lean toward leave the corner case not fully compatible, understand its hacky because we are using single configs, and know this will be better with structured configs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth noting this in the changelog?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Left a few suggestions, PTAL
Don't think there's any major changes required here.
Do we have an open issue and/or follow up PR to clean up the allowed-regex
option?
oauthproxy.go
Outdated
path string | ||
) | ||
|
||
parts := strings.Split(methodPath, "=") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth noting this in the changelog?
oauthproxy.go
Outdated
@@ -70,6 +76,7 @@ type OAuthProxy struct { | |||
AuthOnlyPath string | |||
UserInfoPath string | |||
|
|||
allowedRoutes []*allowedRoute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be to be a pointer or could it just be []allowedRoute
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I weighed the same thing when I was coding this 😄
Switching it to non-pointer since you brought it up too. The struct is pretty lightweight already, pointer doesn't buy us much.
oauthproxy.go
Outdated
path string | ||
) | ||
|
||
parts := strings.Split(methodPath, "=") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about strings.SplitN
here? Then you wouldn't need to rejoin the remainder strings later?
IIRC SplitN
with N==2
should produce a maximum of 2 strings, but if the character is not found, will return a slice of length 1 with the original string in it
oauthproxy_test.go
Outdated
expectedMethods []string | ||
expectedRegexes []string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use a dummy struct for this?
type testAllowedRoute struct {
method string
regexString string
}
...
assert.Equal(t, route.method, expectedRoute[i].method)
assert.Equal(t, route.regexp.String(), expectedRoute[i].regexString)
The benefit of this being that the method and regex are paired, which I would say makes the test easier to read, WDYT?
pkg/validation/allowlist.go
Outdated
msgs := []string{} | ||
for _, route := range o.SkipAuthRoutes { | ||
var regex string | ||
parts := strings.Split(route, "=") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use SplitN
here as well
4b5cf8c
to
0ef3fb2
Compare
Thanks for the notes @JoelSpeed I addressed everything and rebased. |
0ef3fb2
to
d3a05b7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
d3a05b7
to
b7b7ade
Compare
Signed-off-by: hansedong <skipper1314@gmail.com>
Bring over the HTTP Method allowlist & improved validation organization from this defunct PR: #685
Description
Add
--skip-auth-route
option that takes the formMETHOD=PathRegex
orPathRegex
(for backwards compatible with--skip-auth-regex
with the eventual intent on deprecating that option).Motivation and Context
REST APIs might have very different functionality between a GET vs other HTTP methods that alter state. This supports allowlisting an HTTP method for a given regex path.
E.g.
GET /data/1
can be allowlisted to require no authentication, whilePOST /data/1
requires authentication to update the record.How Has This Been Tested?
Unit Tests. TODO - interactive tests
Checklist: