Skip to content

Oauth2 resource param#15147

Merged
snowp merged 15 commits intoenvoyproxy:mainfrom
sudeeptoroy:oauth2_resource_param
Mar 8, 2021
Merged

Oauth2 resource param#15147
snowp merged 15 commits intoenvoyproxy:mainfrom
sudeeptoroy:oauth2_resource_param

Conversation

@sudeeptoroy
Copy link
Contributor

Commit Message: added support for resource param in authorization request
Risk Level: low
Testing: unit test added
Docs Changes: added
Release Notes: na
Platform Specific Features: na
Fixes #15124

Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
@repokitteh-read-only
Copy link

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/envoy/.
API shepherd assignee is @mattklein123
CC @envoyproxy/api-watchers: FYI only for changes made to api/envoy/.

🐱

Caused by: #15147 was opened by sudeeptoroy.

see: more, trace.

Fixed a compilation with test cases

Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>

Signed-off-by: sudeeptoroy <sudeeptoroy@users.noreply.github.com>
@sudeeptoroy sudeeptoroy force-pushed the oauth2_resource_param branch from cde5869 to 0e4849d Compare February 23, 2021 07:30
Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
@moderation
Copy link
Contributor

Oauth2 codeowners @rgs1 @derekargueta @snowp

@rgs1
Copy link
Member

rgs1 commented Feb 25, 2021

cc: @williamsfu99


// Optional resource parameter for authorization request
// RFC: https://tools.ietf.org/html/rfc8707
string resource = 10;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RFC seems to allow multiple values here, should this be a repeated field?

Multiple "resource" parameters MAY be
      used to indicate that the requested token is intended to be used
      at multiple resources.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snowp I will convert this to a repeated field.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snowp Its up for review.

Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
@mattklein123 mattklein123 removed their assignment Mar 1, 2021
@mattklein123
Copy link
Member

/api lgtm

@mattklein123
Copy link
Member

/lgtm api

@repokitteh-read-only repokitteh-read-only bot removed the api label Mar 1, 2021
Comment on lines +102 to +106
std::string h1 = "http://";
std::string h2 = "https://";

for (const auto& resource : resources_protos) {
if (resource.rfind(h1, 0) == 0 || resource.rfind(h2, 0) == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we extract the URL detection logic into its own function?

Currently this allocates two strings every time we do this which seems unnecessary. How about we rewrite this as
absl::StartsWith(resource, "http://") || absl::StartsWith(resource, "https://")?

std::string encodeResourceList(const Protobuf::RepeatedPtrField<std::string>& resources_protos) {
std::string result = "";

if (!resources_protos.empty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this since in the empty case the for loop would terminate immediately

std::string tokenSecret() const { return secret_reader_->tokenSecret(); }
FilterStats& stats() { return stats_; }
const std::string& encodedAuthScopes() const { return encoded_auth_scopes_; }
const std::string encodedResources() const { return encoded_resources_; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return by const & here

config_->encodedAuthScopes(), escaped_redirect_uri, escaped_state);
response_headers->setLocation(new_url);

const std::string resource_param = config_->encodedResources();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use const ref here to avoid a copy

// Auth_scopes was not set, should return default value.
EXPECT_EQ(test_config_->encodedAuthScopes(), TEST_DEFAULT_SCOPE);

// resource by default is not set
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: proper grammar/punctuation in comments

std::string h2 = "https://";

for (const auto& resource : resources_protos) {
if (resource.rfind(h1, 0) == 0 || resource.rfind(h2, 0) == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the RFC it seems like the resource must be an absolute URL, so why do we need this special handling? Is there a reason why we would not percent encode in all cases?

cc @williamsfu99 in case you can shed some light on the the spec here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resource may be in ARN format hence the special case.
"resource":"arn:aws:iam::123456789012:user/12345"

https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snowp @williamsfu99 Let me know what do you think about ARN resource. Also code is up for review again

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a problem supporting the ARN resources, but it seems like we should percent encode it regardless in order to pass it as query param? Are there use cases in the wild where it expects these query parameters to not be URL encoded?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @snowp , here is some information around URI and I agree that it should be url encoded.

absolute URI: The RFC does not mandate the format of the resource param. It's just an identifier and meant to identify the protected resource the client is requesting a token for.
The "resource" parameter URI value is an identifier representing the identity of the resource, which MAY be a locator that corresponds to a network-addressable location where the target resource is hosted.
definition of URI: https://tools.ietf.org/html/rfc3986#section-4.3

I guess, you are in agreement with this.

I will update the PR with URL encoding next.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snowp its up for review

Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks this looks good to me! Just a style nit

@rgs1 Do you wanna give this a quick look as well?

Comment on lines +315 to +317
const std::string& resource_param = config_->encodedResources();

response_headers->setLocation(new_url + resource_param);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small nit but could we rename encodedResources to encodedResourceQueryParams and then inline resource_param like so:

response_headers->setLocation(new_url + config_->encodedResourceQueryParams());

? I think that would read a bit cleaner

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snowp, I have done the changes. The macos tests are failing because go binary could not be installed on the test setup.
Let me know how to move forward from here.

code is up for review

@snowp snowp added the waiting label Mar 3, 2021
Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
@sudeeptoroy
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #15147 (comment) was created by @sudeeptoroy.

see: more, trace.

@sudeeptoroy sudeeptoroy requested a review from snowp March 4, 2021 07:19
@sudeeptoroy
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #15147 (comment) was created by @sudeeptoroy.

see: more, trace.

snowp
snowp previously approved these changes Mar 4, 2021
Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Can you merge main to fix CI?

Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
@sudeeptoroy
Copy link
Contributor Author

Thanks! Can you merge main to fix CI?

Hi @snowp , the CI is fixed now. Requesting you to approve the merge.

@snowp
Copy link
Contributor

snowp commented Mar 5, 2021

@sudeeptoroy Sorry could you add a release note for this? Thanks!

Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
@sudeeptoroy
Copy link
Contributor Author

@sudeeptoroy Sorry could you add a release note for this? Thanks!

Hi @snowp, I have added a release note. Can you review it and let me know if wordings are fine?

Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Release note looks good besides one minor language suggestion! Thanks for your patience in iterating on this PR

* json: introduced new JSON parser (https://github.com/nlohmann/json) to replace RapidJSON. The new parser is disabled by default. To test the new RapidJSON parser, enable the runtime feature `envoy.reloadable_features.remove_legacy_json`.
* kill_request: :ref:`Kill Request <config_http_filters_kill_request>` Now supports bidirection killing.
* log: added a new custom flag ``%j`` to the log pattern to print the actual message to log as JSON escaped string.
* oauth filter: added the optional parameter :ref:`resources <envoy_v3_api_field_extensions.filters.http.oauth2.v3alpha.OAuth2Config.resources>`. Set this value to add multiple "resource" parameters in the Authorization request sent to the OAuth provider. This acts as an identifier representing protected resource the client is requesting a token for.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

representing protected resource -> representing the protected resources

Copy link
Contributor Author

@sudeeptoroy sudeeptoroy Mar 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @snowp , I have made the corresponding change.

Signed-off-by: Sudeepto Roy <sudeepto.roy@gmail.com>
Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@snowp snowp merged commit 471c609 into envoyproxy:main Mar 8, 2021
@sudeeptoroy sudeeptoroy deleted the oauth2_resource_param branch March 8, 2021 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add optional "resource" indicator parameter along with other params for the OAuth2 Authorization request workflow

5 participants