- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1.4k
          fix: Prefer the token_endpoint_auth_method response from DCR registration 
          #1022
        
          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
  
    fix: Prefer the token_endpoint_auth_method response from DCR registration 
  
  #1022
              Conversation
        
          
                src/client/auth.ts
              
                Outdated
          
        
      | * server. | ||
| */ | ||
| clientInformation(): OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>; | ||
| clientInformation(): OAuthClientInformationFull | undefined | Promise<OAuthClientInformationFull | undefined>; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this type signature change worries me a bit.  The OAuthClientInformation is the response from the DCR endpoint, listed here:
https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.1
All the fields are optional except for redirect_uris (which is what I think is what required a bunch of changes in tests).
this means this change will be backwards incompatible for implementations of the provider that directly return the DCR response rather than the full metadata.
saveClientInformation takes the full information type, so this might be a non issue.
to land this, we'll either want to:
- check around for implementations to see if they commonly return the reduced type, to see the estimated impact of the breaking change
- OR: make this backwards compatible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood. I can make it backwards compatible. My only argument for changing the type is that it seems like the current type is wrong. As you pointed out, saveClientInformation() takes the OAuthClientInformationFull type and is the only way clientInformation() is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about this a bit more and chatted w/ @ochafik & @felixweinberger .
There's 2 flows to consider:
- DCR Request + Response
- Saving and restoring client information
For the DCR Request + Response, requiring redirect_uri's in both cases is correct. We require sending one, and the DCR response is required to send back any data related to the client:
Additionally, the authorization server MUST return all registered
metadata about this client, including any fields provisioned by the
authorization server itself.
However, saveClientInformation and clientInformation are used in non-DCR flows as well.  In static registration situations, providing the redirect URI's isn't required and are often not available. Similarly, with the upcoming Client ID Metadata Document flow, the list of redirect URI's will not be on the client necessarily.
So what that means is:
- OAuthClientInformationFullcould more properly be named- OAuthDCRResponseMetadata(or something similar). Although renaming here isn't strictly necessary.
- HaveOAuthClientInformationFullbe an optional type for bothsaveClientInformationandclientInformation
- Also allow OAuthClientInformationas a type in both cases
That will loosen the type to accommodate both DCR and non-DCR cases, and also allow us to get the supported token_endpoint_auth_method in the DCR response if it's available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pcarleton understood. will follow up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pcarleton I have redone the PR.
- Adds a new type to src/shared/auth.ts:
export type OAuthClientInformationMixed = OAuthClientInformation | OAuthClientInformationFull;- Applies new type to the auth flow in src/client/auth.ts
- Updates example client src/examples/client/simpleOAuthClient.ts
- Adds tests for selectClientAuthMethodto src/client/auth.test.ts
| addClientAuthentication(headers, params, authorizationServerUrl, metadata); | ||
| } else { | ||
| // Determine and apply client authentication method | ||
| const supportedMethods = metadata?.token_endpoint_auth_methods_supported ?? []; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a less intrusive solution would be the following:
const supportedMethods = clientInformation.token_endpoint_auth_method ? [clientInformation.token_endpoint_auth_method] : (metadata?.token_endpoint_auth_methods_supported ?? [])There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed this is less intrusive, but it has a slightly different behavior. If the metadata has "token_endpoint_auth_methods_supported": ["none"] and the client registration endpoint returns "token_endpoint_auth_method": "client_secret_post", this code would bypass the metadata's "supported" value. Is that allowed?
https://www.rfc-editor.org/rfc/rfc8414.html
token_endpoint_auth_methods_supported
OPTIONAL. JSON array containing a list of client authentication methods supported by this token endpoint. Client authentication method values are used in the "token_endpoint_auth_method" parameter defined in Section 2 of [RFC7591]. If omitted, the default is "client_secret_basic" -- the HTTP Basic Authentication Scheme specified in Section 2.3.1 of OAuth 2.0 [RFC6749].
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I guess that's unlikely, but still possible 😊
110b067    to
    9bda5df      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, LGTM! Thanks for the patience
Updates the OAuth authorization flow to prefer to use the
token_endpoint_auth_methodresult from the Dynamic Client Registration endpoint, if provided.Motivation and Context
When using dynamic client registration, the registration endpoint may return the
token_endpoint_auth_methodvalue to be used when exchanging tokens for access tokens. The current oauth implementation ignores this field and only uses the methods from the oauth authorization server metadata.How Has This Been Tested?
This has not been tested in a real application.
Breaking Changes
No breaking changes.
Types of changes
Checklist
Additional context
Previous PR #982 is no longer showing changes after rebase for some reason and was automatically closed, reopening new PR