Skip to content

Commit

Permalink
filters/auth: document forwardToken key sorting
Browse files Browse the repository at this point in the history
Add a note that forwardToken JSON value has sorted keys and
can be used as a ratelimit key.

Signed-off-by: Alexander Yastrebov <alexander.yastrebov@zalando.de>
  • Loading branch information
AlexanderYastrebov committed Oct 10, 2023
1 parent 79a9f35 commit bbc0fbf
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 8 deletions.
2 changes: 2 additions & 0 deletions docs/reference/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -1467,6 +1467,8 @@ jwtValidation("https://login.microsoftonline.com/{tenantId}/v2.0")

The filter takes the header name as its first argument and sets header value to the
token info or token introspection result serialized as a JSON object.
JSON object keys (as well keys of object values) are sorted therefore
header value is stable and can be used e.g. as a ratelimit key.
To include only particular fields provide their names as additional arguments.

If this filter is used when there is no token introspection or token info data
Expand Down
1 change: 1 addition & 0 deletions filters/auth/forwardtoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func (f *forwardTokenFilter) Request(ctx filters.FilterContext) {
}
}

// Produces payload with sorted keys
payload, err := json.Marshal(tiMap)
if err != nil {
ctx.Logger().Errorf("Error while marshaling token: %v.", err)
Expand Down
27 changes: 19 additions & 8 deletions filters/auth/forwardtoken_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func staticServer(content string) *httptest.Server {
}

func TestForwardToken(t *testing.T) {
tokeninfoServer := staticServer(`{"uid": "test", "scope": ["uid"]}`)
tokeninfoServer := staticServer(`{"uid": "test", "scope": ["uid"], "obj": {"foo": "bar", "baz": "qux"}}`)
defer tokeninfoServer.Close()

introspectionServer := staticServer(`{"uid": "test-uid", "sub": "test-sub", "claims": {"email": "test@test.com"}, "active": true}`)
Expand All @@ -38,7 +38,7 @@ func TestForwardToken(t *testing.T) {
filters: `oauthTokeninfoAnyScope("uid") -> forwardToken("X-Skipper-Tokeninfo")`,
header: http.Header{},
expectedHeader: http.Header{
"X-Skipper-Tokeninfo": []string{`{"scope":["uid"],"uid":"test"}`},
"X-Skipper-Tokeninfo": []string{`{"obj":{"baz":"qux","foo":"bar"},"scope":["uid"],"uid":"test"}`},
},
},
{
Expand All @@ -49,10 +49,18 @@ func TestForwardToken(t *testing.T) {
},
},
{
filters: `oauthTokeninfoAnyScope("uid") -> forwardToken("X-Skipper-Tokeninfo", "uid", "scope")`,
filters: `oauthTokeninfoAnyScope("uid") -> forwardToken("X-Skipper-Tokeninfo", "uid", "scope", "obj")`,
header: http.Header{},
expectedHeader: http.Header{
"X-Skipper-Tokeninfo": []string{`{"scope":["uid"],"uid":"test"}`},
"X-Skipper-Tokeninfo": []string{`{"obj":{"baz":"qux","foo":"bar"},"scope":["uid"],"uid":"test"}`},
},
},
{
// JSON value keys are sorted
filters: `oauthTokeninfoAnyScope("uid") -> forwardToken("X-Skipper-Tokeninfo", "obj", "scope", "uid")`,
header: http.Header{},
expectedHeader: http.Header{
"X-Skipper-Tokeninfo": []string{`{"obj":{"baz":"qux","foo":"bar"},"scope":["uid"],"uid":"test"}`},
},
},
{
Expand All @@ -77,21 +85,24 @@ func TestForwardToken(t *testing.T) {
},
},
{
filters: `forwardToken("X-Skipper-Tokeninfo")`, // not tokeninfo or tokenintrospection
// not tokeninfo or tokenintrospection
filters: `forwardToken("X-Skipper-Tokeninfo")`,
header: http.Header{},
expectedHeader: http.Header{},
},
{
filters: `oauthTokeninfoAnyScope("uid") -> forwardToken("X-Skipper-Tokeninfo")`, // overwrites existing
// overwrites existing
filters: `oauthTokeninfoAnyScope("uid") -> forwardToken("X-Skipper-Tokeninfo")`,
header: http.Header{
"X-Skipper-Tokeninfo": []string{`{"already": "exists"}`},
},
expectedHeader: http.Header{
"X-Skipper-Tokeninfo": []string{`{"scope":["uid"],"uid":"test"}`},
"X-Skipper-Tokeninfo": []string{`{"obj":{"baz":"qux","foo":"bar"},"scope":["uid"],"uid":"test"}`},
},
},
{
filters: `forwardToken("X-Skipper-Tokeninfo")`, // not tokeninfo or tokenintrospection, passes existing
// not tokeninfo or tokenintrospection, passes existing
filters: `forwardToken("X-Skipper-Tokeninfo")`,
header: http.Header{
"X-Skipper-Tokeninfo": []string{`{"already": "exists"}`},
},
Expand Down

0 comments on commit bbc0fbf

Please sign in to comment.