Skip to content
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 GET method on user info endpoint (oauth) #11014

Merged
merged 1 commit into from
Mar 11, 2022

Conversation

mdesmet
Copy link
Contributor

@mdesmet mdesmet commented Feb 10, 2022

Description

General information

Is this change a fix, improvement, new feature, refactoring, or other?

This is new feature

Is this a change to the core query engine, a connector, client library, or the SPI interfaces? (be specific)

It's a change to the core query engine

How would you describe this change to a non-technical end user or system administrator?

This feature allows to configure the requests method of the user info endpoint for oauth2 authentication for web ui and jdbc/odbc drivers.

Related issues, pull requests, and links

Documentation

( ) No documentation is needed.
( *) Sufficient documentation is included in this PR.
( ) Documentation PR is available with #prnumber.
( ) Documentation issue #issuenumber is filed, and can be handled later.

Release notes

( *) No release notes entries required.
( ) Release notes entries required with the following suggested text:

@@ -332,7 +333,7 @@ else if (nonce.isPresent() != oauth2Response.getIdToken().isPresent()) {
if (userinfoUri.isPresent()) {
// validate access token is trusted by remote userinfo endpoint
Request request = Request.builder()
.setMethod(POST)
.setMethod(userInfoRequestMethod)
Copy link
Member

Choose a reason for hiding this comment

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

Can we simply change it to GET?

Copy link
Member

Choose a reason for hiding this comment

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

Both methods are allowed according to the spec.

Copy link
Member

Choose a reason for hiding this comment

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

According to https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest GET is recommended. The thing that we can use both methods does not mean we need to. I would prefer to have less toggles and use GET if is more widely. The issue is that we need to make sure we don't introduce regression.

@@ -332,7 +333,7 @@ else if (nonce.isPresent() != oauth2Response.getIdToken().isPresent()) {
if (userinfoUri.isPresent()) {
// validate access token is trusted by remote userinfo endpoint
Request request = Request.builder()
.setMethod(POST)
.setMethod(userInfoRequestMethod)
Copy link
Member

Choose a reason for hiding this comment

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

Both methods are allowed according to the spec.

@ConfigDescription("userinfo request method")
public OAuth2Config setUserInfoRequestMethod(String userInfoRequestMethod)
{
this.userInfoRequestMethod = userInfoRequestMethod;
Copy link
Member

Choose a reason for hiding this comment

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

Please add

@PostConstruct
public void validate()
{
}

ensuring that a valid HTTP method name was provided and a test for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added the method and verified the valid states using checkState

@@ -45,6 +46,7 @@
private String tokenUrl;
private String jwksUrl;
private Optional<String> userinfoUrl = Optional.empty();
private String userInfoRequestMethod = POST;
Copy link
Member

Choose a reason for hiding this comment

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

userinfoUrl uses a different casing

Copy link
Member

Choose a reason for hiding this comment

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

Since userinforUrl is optional, so userinforRequestMethod should be optional as well. Configuring:

http-server.authentication.oauth2.userinfo-request-method=GET

shouldn't be allowed without http-server.authentication.oauth2.userinfo-url specified.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All remarks have been processed. I've changed the casing, made the property optional and added state checks.

@mdesmet mdesmet force-pushed the oidc_support_get_user_endpoint branch 4 times, most recently from 5ce060e to 5c0f901 Compare February 12, 2022 21:48
@@ -45,6 +50,7 @@
private String tokenUrl;
private String jwksUrl;
private Optional<String> userinfoUrl = Optional.empty();
private Optional<String> userinfoRequestMethod = Optional.empty();
Copy link
Member

Choose a reason for hiding this comment

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

Why is this configurable? Does oauth2 specify both methods for this type of API?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

@11xor6 11xor6 left a comment

Choose a reason for hiding this comment

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

LGTM

@@ -332,7 +334,7 @@ else if (nonce.isPresent() != oauth2Response.getIdToken().isPresent()) {
if (userinfoUri.isPresent()) {
// validate access token is trusted by remote userinfo endpoint
Request request = Request.builder()
.setMethod(POST)
.setMethod(userInfoRequestMethod.orElse(POST))
Copy link
Member

Choose a reason for hiding this comment

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

Let's simply use GET

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What about the risk of regression?

I'm good to change to GET, just a little worried it might break for some existing users: I've seen many custom OAuth enterprise implementations, not always strictly according spec.

Copy link
Member

Choose a reason for hiding this comment

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

I think @lukasz-walkiewicz have tested all the IdP we think we support and it was working just fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No doubt the commercial idp will work with both POST or GET. I see rather the risk within custom built oidc implementations. if their custom oidc implementation only has the POST endpoint and suddenly it's not working anymore after a Trino upgrade. As I said already, for me it's ok to make the change to GET. Will adapt the code later today.

Copy link
Member

Choose a reason for hiding this comment

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

We are not aware of any use case like this. Also it sounds very exotic, I would prefer not to support such use cases without hard evidence it is actually needed.

@mdesmet mdesmet force-pushed the oidc_support_get_user_endpoint branch from 5c0f901 to 49972fb Compare March 10, 2022 21:48
@kokosing
Copy link
Member

No release notes are needed here.

@kokosing kokosing merged commit 74661d6 into trinodb:master Mar 11, 2022
@kokosing
Copy link
Member

Merged, thanks!

@github-actions github-actions bot added this to the 374 milestone Mar 11, 2022
@mdesmet mdesmet deleted the oidc_support_get_user_endpoint branch March 15, 2022 12:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

OAuth2 userInfoUrl request method cannot be configured
5 participants