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

[Java Client] Make Audience Field Optional in OAuth2 Client Credentials #11988

Conversation

michaeljmarshall
Copy link
Member

Motivation

When reviewing #11931, I noticed that the audience field on the ClientCredentialsExchangeRequest is not optional, but it should be. Only some Identity Providers require this field. Auth0 is one such provider. Azure AD, for example, does not require this field. Thus, we shouldn't require the field.

Modifications

  • Modify buildClientCredentialsBody to only add audience when it is non empty and non null. Note that previously, the audience field was not allowed to be empty or null. Thus, only setting it on the bodyMap when it is non empty and non null will result in backwards compatible changes for all clients.
  • Modify buildClientCredentialsBody to reduce code duplication in tests
  • Updated documentation
  • Updated 2 tests and added another to ensure coverage

Verifying this change

Added new test and modified two existing tests.

Does this pull request potentially affect one of the following parts:

It modifies the public api in that it allows for the audience field to now be null or the empty string. In both cases, the field will not be sent to the Identity Provider. This not a breaking change.

Documentation

I updated the latest docs. If this change gets cherry picked to branch-2.8 or branch-2.7, we will need to update the docs for those versions.

@michaeljmarshall michaeljmarshall changed the title [Java Client] Make Audience Field in Client Credentials Optional [Java Client] Make Audience Field Optional in OAuth2 Client Credentials Sep 9, 2021
@BewareMyPower
Copy link
Contributor

Good job! I also found this issue when I learn Azure OAuth 2.0 long time ago but forgot to fix it.

@Anonymitaet Anonymitaet added the doc Your PR contains doc changes, no matter whether the changes are in markdown or code files. label Sep 10, 2021
@Anonymitaet
Copy link
Member

@michaeljmarshall thanks for adding docs for master! Please do not forget to add docs to other versions if applicable. Then you can ping me to review, thanks.

@@ -46,7 +46,7 @@ The following parameters are supported:
| `type` | Oauth 2.0 auth type. Optional. | default: `client_credentials` |
| `issuerUrl` | URL of the provider which allows Pulsar to obtain an access token. Required. | `https://accounts.google.com` |
| `privateKey` | URL to a JSON credentials file (in JSON format; see below). Required. | See "Supported Pattern Formats" |
| `audience` | An OAuth 2.0 "resource server" identifier for the Pulsar cluster. Required. | `https://broker.example.com` |
| `audience` | An OAuth 2.0 "resource server" identifier for the Pulsar cluster. Required by some Identity Providers. Optional for client. | `https://broker.example.com` |
Copy link
Member

Choose a reason for hiding this comment

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

Optional for client. => Optional for java client.?

Just a note, we also need to make this field optional for other language clients that support oauth authentication (e.g. cpp, python, golang), otherwise, there may be inconsistent behavior, e.g. for java language this field is optional and for cpp this field is required, can you create several issues, in order for us to track this thing

@@ -28,7 +28,7 @@ The following table lists parameters supported for the `client credentials` auth
| `type` | Oauth 2.0 authentication type. | `client_credentials` (default) | Optional |
| `issuerUrl` | URL of the authentication provider which allows the Pulsar client to obtain an access token | `https://accounts.google.com` | Required |
| `privateKey` | URL to a JSON credentials file | Support the following pattern formats: <br> <li> `file:///path/to/file` <li>`file:/path/to/file` <li> `data:application/json;base64,<base64-encoded value>` | Required |
| `audience` | An OAuth 2.0 "resource server" identifier for the Pulsar cluster | `https://broker.example.com` | Required |
| `audience` | An OAuth 2.0 "resource server" identifier for the Pulsar cluster | `https://broker.example.com` | Optional |
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if updating this field to be optional will cause confusion for users using other languages, one suggestion I have is to keep this field as required until other languages implement this change

@@ -29,7 +29,7 @@ The following table lists parameters supported for the `client credentials` auth
| `type` | Oauth 2.0 authentication type. | `client_credentials` (default) | Optional |
| `issuerUrl` | URL of the authentication provider which allows the Pulsar client to obtain an access token | `https://accounts.google.com` | Required |
| `privateKey` | URL to a JSON credentials file | Support the following pattern formats: <br> <li> `file:///path/to/file` <li>`file:/path/to/file` <li> `data:application/json;base64,<base64-encoded value>` | Required |
| `audience` | An OAuth 2.0 "resource server" identifier for the Pulsar cluster | `https://broker.example.com` | Required |
| `audience` | An OAuth 2.0 "resource server" identifier for the Pulsar cluster. Required by some Identity Providers. | `https://broker.example.com` | Optional |
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if updating this field to be optional will cause confusion for users using other languages, one suggestion I have is to keep this field as required until other languages implement this change

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 understand what would be the benefit of this suggestion. This change looks good to me.

@michaeljmarshall
Copy link
Member Author

@eolivelli - PTAL

@EronWright
Copy link
Contributor

Something to be aware of, some of the client implementations use audience field as a key into the token persistence layer. I suppose the service URL should be used instead. It is important to isolate the tokens for each resource server (Pulsar cluster).

@michaeljmarshall
Copy link
Member Author

Something to be aware of, some of the client implementations use audience field as a key into the token persistence layer. I suppose the service URL should be used instead. It is important to isolate the tokens for each resource server (Pulsar cluster).

@EronWright - can you clarify which client implementations you're referring to? Since the field will still exist, I don't think we're breaking any compatibility here. Is there documentation you think we should update?

@EronWright
Copy link
Contributor

@michaeljmarshall I don't know of any Java implementations that do, but I was thinking about pulsarctl since it maintains a token cache based on audience (example). I mention it to raise awareness.

@Anonymitaet
Copy link
Member

Hi @michaeljmarshall would you like to add docs to Pulsar? Something like:
image

@BewareMyPower
Copy link
Contributor

BewareMyPower commented Oct 15, 2021

@michaeljmarshall I don't know of any Java implementations that do, but I was thinking about pulsarctl since it maintains a token cache based on audience (example). I mention it to raise awareness.

I think it doesn't make a difference. If Golang client also makes audience field optional in future, the Audience field will still exist.

type Issuer struct {
    IssuerEndpoint string
    ClientID       string
    Audience       string
} 

The only affected code might be here that audience could be nil.

func (f *MemoryStore) SaveGrant(audience string, grant oauth2.AuthorizationGrant) error {
	f.lock.Lock()
	defer f.lock.Unlock()
	f.grants[audience] = &grant
	return nil
}

I think adding a null check will be okay. @EronWright Please confirm it.

Copy link
Member

@lhotari lhotari left a comment

Choose a reason for hiding this comment

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

LGTM

@michaeljmarshall
Copy link
Member Author

@lhotari, @tuteng, @BewareMyPower - what is the preferred way to resolve conflicts here? The contributor's guide advises against pushing with force and thus against rebasing, but merging master into my branch will add a ton of extra commits.

@BewareMyPower
Copy link
Contributor

I'd like the rebase way.

@michaeljmarshall michaeljmarshall force-pushed the client-creds-flow-make-audience-optional branch from 5fe6804 to 02edee2 Compare November 24, 2021 04:54
@michaeljmarshall
Copy link
Member Author

@BewareMyPower - thank you for your input. I went ahead and rebased my branch.

@Anonymitaet - in my most recent commit, I updated the section of the documentation you highlighted above. Thank you for pointing out that section!

@michaeljmarshall
Copy link
Member Author

@BewareMyPower
Copy link
Contributor

LGTM, but I'm not sure if it's proper to merge this PR at this moment.

@lhotari
Copy link
Member

lhotari commented Dec 2, 2021

Closing and re-opening to run against latest master branch changes. GitHub creates a new merge commit internally when that happens. Another option would be to rebase or push new commits to the PR.

@lhotari lhotari closed this Dec 2, 2021
@lhotari lhotari reopened this Dec 2, 2021
@michaeljmarshall
Copy link
Member Author

LGTM, but I'm not sure if it's proper to merge this PR at this moment.

@BewareMyPower why wouldn't it be proper? I think I might be missing some context.

@BewareMyPower
Copy link
Contributor

Just a concern about backward compatibility like what @EronWright mentioned. From my perspective, it doesn't break the compatibility. So I think we can merge it.

@lhotari lhotari closed this Dec 2, 2021
@lhotari lhotari reopened this Dec 2, 2021
@lhotari lhotari merged commit b2b5463 into apache:master Dec 3, 2021
@michaeljmarshall michaeljmarshall deleted the client-creds-flow-make-audience-optional branch December 3, 2021 05:01
lhotari pushed a commit that referenced this pull request Dec 3, 2021
…ls (#11988)

* [Java Client] Make Audience Field in Client Credentials Optional

* Update site2/website-next/docs

* Remove update to 2.8.1 docs

* Update more docs based on code review

(cherry picked from commit b2b5463)
lhotari pushed a commit that referenced this pull request Dec 3, 2021
…ls (#11988)

* [Java Client] Make Audience Field in Client Credentials Optional

* Update site2/website-next/docs

* Remove update to 2.8.1 docs

* Update more docs based on code review

(cherry picked from commit b2b5463)
@lhotari lhotari added cherry-picked/branch-2.8 Archived: 2.8 is end of life cherry-picked/branch-2.9 Archived: 2.9 is end of life release/2.8.2 release/2.9.1 labels Dec 3, 2021
@lhotari lhotari added this to the 2.10.0 milestone Dec 3, 2021
fxbing pushed a commit to fxbing/pulsar that referenced this pull request Dec 19, 2021
…ls (apache#11988)

* [Java Client] Make Audience Field in Client Credentials Optional

* Update site2/website-next/docs

* Remove update to 2.8.1 docs

* Update more docs based on code review
* @return Generate the final request body from a map.
*/
String buildClientCredentialsBody(Map<String, String> bodyMap) {
String buildClientCredentialsBody(ClientCredentialsExchangeRequest req) {
Map<String, String> bodyMap = new TreeMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you explain why do you use a TreeMap here? I'm not sure if the order makes a difference.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's only a TreeMap because I copied it from exchangeClientCredentials. I don't remember any specific reason for using this data structure.

momo-jun added a commit to momo-jun/pulsar that referenced this pull request Aug 4, 2022
momo-jun added a commit to momo-jun/pulsar that referenced this pull request Aug 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/client cherry-picked/branch-2.8 Archived: 2.8 is end of life cherry-picked/branch-2.9 Archived: 2.9 is end of life doc Your PR contains doc changes, no matter whether the changes are in markdown or code files. release/2.8.2 release/2.9.1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants