Skip to content

Commit

Permalink
filters/auth: add second login redirect stub placeholder (#3161)
Browse files Browse the repository at this point in the history
Login redirect stub introduced by #3028 uses `{{authCodeURL}}` placeholder
that is a valid mustache template and hence inconvenient to use from
mustache templates.

This change adds a second `{authCodeURL}` placeholder and
`X-Auth-Code-Url` response header.

Signed-off-by: Alexander Yastrebov <[email protected]>
  • Loading branch information
AlexanderYastrebov authored Jul 22, 2024
1 parent 5a4b32d commit 35195d0
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
13 changes: 7 additions & 6 deletions docs/reference/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -1685,8 +1685,9 @@ authz and access control.

The filter also supports javascript login redirect stub that can be used e.g. to store location hash.
To enable the stub, add preceding [annotate](#annotate) filter with `oauthGrant.loginRedirectStub` key and
HTML content that will be served to the client instead of `307 Temporary Redirect` to the authorization URL.
The filter will replace `{{authCodeURL}}` placeholder in the content with the actual authorization URL.
content that will be served to the client with `200 OK` status instead of `307 Temporary Redirect` to the authorization URL.
The filter will replace `{authCodeURL}` (and `{{authCodeURL}}`) placeholders in the content with the actual authorization URL
and add `X-Auth-Code-Url` response header with the same value.

See the [tutorial](../tutorials/auth.md#oauth2-authorization-grant-flow) for step-by-step
instructions.
Expand All @@ -1712,7 +1713,7 @@ single_page_app:
if (window.location.hash !== null) {
localStorage.setItem('original-location-hash', window.location.hash);
}
window.location.replace('{{authCodeURL}}');
window.location.replace('{authCodeURL}');
</script>
</head>
</html>
Expand Down Expand Up @@ -2068,10 +2069,10 @@ The filter also honors the `skip-request-body-parse` of the corresponding [confi
### awsSigv4

This filter signs request using [AWS Sig V4](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html_) algorithm. The requests must provide following headers in order for this filter to generate a valid signature.
- `x-amz-accesskey` header must contain a valid AWS access key
- `x-amz-accesskey` header must contain a valid AWS access key
- `x-amz-secret` header must contain a valid secret for AWS client being used.
- `x-amz-time` header must contain the time in RFC3339 format which this filter can use to generate signature and `X-Amz-Date` header on signed request. This time stamp is considered as the time stamp of generated signature.
- `x-amz-session` must contain valid AWS session token ([see](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html#using-temp-creds-sdk)) to be set as `X-Amz-Security-Token` in signed request when `DisableSessionToken` parameter defined on route is set to false.
- `x-amz-session` must contain valid AWS session token ([see](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html#using-temp-creds-sdk)) to be set as `X-Amz-Security-Token` in signed request when `DisableSessionToken` parameter defined on route is set to false.

Filter removes these headers after reading the values. Once the signature is generated, it is appended to existing Authorization header or if there is no exisiting Authorization header, added as new and forwarded to AWS service.

Expand All @@ -2097,7 +2098,7 @@ This filter expects
- `DisableSessionToken` Disables setting the session token on the request as part of signing through X-Amz-Security-Token. This is needed for variations of v4 that
present the token elsewhere.



#### Memory consideration
This filter reads the body in memory. This is needed to generate signature as per Signature V4 specs. Special considerations need to be taken when operating the skipper with concurrent requests.
Expand Down
4 changes: 3 additions & 1 deletion filters/auth/grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,12 @@ func loginRedirectWithOverride(ctx filters.FilterContext, config *OAuthConfig, o

if lrs, ok := annotate.GetAnnotations(ctx)["oauthGrant.loginRedirectStub"]; ok {
lrs = strings.ReplaceAll(lrs, "{{authCodeURL}}", authCodeURL)
lrs = strings.ReplaceAll(lrs, "{authCodeURL}", authCodeURL)
ctx.Serve(&http.Response{
StatusCode: http.StatusOK,
Header: http.Header{
"Content-Length": []string{strconv.Itoa(len(lrs))},
"Content-Length": []string{strconv.Itoa(len(lrs))},
"X-Auth-Code-Url": []string{authCodeURL},
},
Body: io.NopCloser(strings.NewReader(lrs)),
})
Expand Down
12 changes: 9 additions & 3 deletions filters/auth/grant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ func TestGrantLoginRedirectStub(t *testing.T) {

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

const stubContent = "stub content"
const stubContent = "foo {{authCodeURL}} bar {authCodeURL} baz"

routes := eskip.MustParse(fmt.Sprintf(`*
-> annotate("oauthGrant.loginRedirectStub", "%s")
Expand All @@ -1027,6 +1027,12 @@ func TestGrantLoginRedirectStub(t *testing.T) {
require.NoError(t, err)

assert.Equal(t, rsp.StatusCode, http.StatusOK)
assert.Equal(t, int64(len(stubContent)), rsp.ContentLength)
assert.Equal(t, stubContent, string(body))

authCodeUrl := rsp.Header.Get("X-Auth-Code-Url")
assert.True(t, strings.HasPrefix(authCodeUrl, provider.URL))

expectedContent := fmt.Sprintf("foo %s bar %s baz", authCodeUrl, authCodeUrl)

assert.Equal(t, int64(len(expectedContent)), rsp.ContentLength)
assert.Equal(t, expectedContent, string(body))
}

0 comments on commit 35195d0

Please sign in to comment.