Skip to content

[19.0] [IMP] webservice: configurable OAuth2 token request - #143

Open
ivantodorovich wants to merge 3 commits into
OCA:19.0from
camptocamp:19.0-imp-webservice-oauth2-client-auth
Open

[19.0] [IMP] webservice: configurable OAuth2 token request#143
ivantodorovich wants to merge 3 commits into
OCA:19.0from
camptocamp:19.0-imp-webservice-oauth2-client-auth

Conversation

@ivantodorovich

@ivantodorovich ivantodorovich commented Jul 2, 2026

Copy link
Copy Markdown

Some providers require the credentials in a non-standard Authorization header (for instance Okta uses Authorization: SSWS <token>).

This PR makes it possible. Such an endpoint can be configured as:

Auth Type             = OAuth2
OAuth2 Flow           = Backend Application (Client Credentials Grant)
Token URL             = https://provider.example.com/oauth2/token
Client Authentication = Custom Authorization header
Client Auth Header    = Authorization
Client Auth Value     = SSWS <token>

Additionally, the provider might only reply to GET instead of POST, so the token request method is configurable now too.

@OCA-git-bot

Copy link
Copy Markdown
Contributor

Hi @etobella,
some modules you are maintaining are being modified, check this out!

@OCA-git-bot OCA-git-bot added mod:webservice Module webservice mod:webservice_server_env Module webservice_server_env series:19.0 labels Jul 2, 2026
@ivantodorovich
ivantodorovich force-pushed the 19.0-imp-webservice-oauth2-client-auth branch 2 times, most recently from d3ee41b to 2d54f31 Compare July 2, 2026 18:37
Until now the OAuth2 "Backend Application (Client Credentials)" flow
always requested the token in one fixed way: an HTTP POST where the
client id and secret were turned into an HTTP Basic Authorization header
(this is what oauthlib does by default). Providers that deviate from
that could not be used.

Two configuration options are added to the webservice backend so those
providers can be supported through configuration only:

- Token Request Method: POST (default) or GET, for providers that expose
  the token endpoint as a GET.

- Client Authentication: how the client credentials are presented to the
  token endpoint:
    * Client ID & Secret (HTTP Basic) (default): the previous behavior,
      unchanged.
    * Custom Authorization header: a static, verbatim header value (for
      example "SSWS <token>"). In this case the Client ID / Client Secret
      fields are not used; the header name and value are configured
      directly instead.

The defaults keep the exact same behavior as before, so existing
backends are not affected. The custom header is injected through a small
requests auth handler so that oauthlib does not overwrite it with its
automatic Basic Authorization header.

Two validation rules make sure the right fields are filled in depending
on the chosen client authentication: the client id and secret for the
HTTP Basic method, or the header name and value for the custom header
method.
There was a misuse of `and` instead of `or` in the `invisible` attribute of some
fields that are specific to the Web Application flow
@ivantodorovich
ivantodorovich force-pushed the 19.0-imp-webservice-oauth2-client-auth branch from 2d54f31 to fd38ba6 Compare July 2, 2026 18:46
The webservice module gained new OAuth2 configuration fields (the token
request method, the client authentication method, and the custom
Authorization header name and value). These are now also manageable
through server environment configuration files, like the other
webservice fields.
@ivantodorovich
ivantodorovich force-pushed the 19.0-imp-webservice-oauth2-client-auth branch from fd38ba6 to 5c14c1f Compare July 2, 2026 18:56
@ivantodorovich
ivantodorovich marked this pull request as ready for review July 2, 2026 18:57
@OCA-git-bot

Copy link
Copy Markdown
Contributor

This PR has the approved label and has been created more than 5 days ago. It should therefore be ready to merge by a maintainer (or a PSC member if the concerned addon has no declared maintainer). 🤖

@ivantodorovich

Copy link
Copy Markdown
Author

Hello @etobella 👋🏻

What do you think about this?

@simahawk simahawk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LG overall. Minor remark on form modifiers

name="oauth2_clientid"
invisible="auth_type != 'oauth2'"
required="auth_type == 'oauth2'"
invisible="auth_type != 'oauth2' or (oauth2_flow == 'backend_application' and oauth2_client_auth_method != 'client_secret_basic')"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

wouldn't be better to have a flag to compute this condition? Eg: oauth2_clientid_is_visible

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Not sure.

We'd need at least two fields:
oauth2_client_secret_fields_visible (for oauth2_clientid + oauth2_client_secret)
oauth2_client_custom_header_fields_visible (for oauth2_client_auth_header + oauth2_client_auth_value)

Personally, I'm more inclined to keep them inline in the view, and avoid paying the cost of the dedicated computed fields (a backend request roundtrip) -- IMHO it's not complex enough.. but I'm willing to change if you disagree

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants