88 Commits

Author SHA1 Message Date
Jacques Dafflon
a3f34289fa fix(rp): don't ignore JWKS parsing errors (#771)
This safely ignores unknown key type errors on JWKS while returning all
other errors. Returned errors are wrap to easily identify which key in
the set is problematic if any.

Jose v4.0.3 was handling this correctly according to spec, but it was
reverted in v4.0.4 as the implementation was a breaking change due to
the custom UnmarshalJSON on the key set. For details see:
- https://github.com/go-jose/go-jose/issues/136
- https://github.com/go-jose/go-jose/pull/137

Jose v4.0.4 also provided a handy static error to check for unknown web
key types. Sadly this was removed: a prefix match on the error message
is the best option until Jose improves it's error handling.

Hopefully, Jose will not change the error message in a patch or minor
version release. But just in case, test cases have been added to detect
it.

Closes #541

### Definition of Ready

- [x] I am happy with the code
- [x] Short description of the feature/issue is added in the pr
description
- [x] PR is linked to the corresponding user story
- [ ] Acceptance criteria are met
- [ ] All open todos and follow ups are defined in a new ticket and
justified
- [ ] Deviations from the acceptance criteria and design are agreed with
the PO and documented.
- [x] No debug or dead code
- [x] My code has no repetitions
- [x] Critical parts are tested automatically
- [x] Where possible E2E tests are implemented
- [x] Documentation/examples are up-to-date
- [x] All non-functional requirements are met
- [ ] Functionality of the acceptance criteria is checked manually on
the dev system.

Co-authored-by: Wim Van Laer <wim07101993@users.noreply.github.com>
2025-12-03 11:46:51 +01:00
Jacques Dafflon
e3169b695f feat(rp): add WithPKCEFromDisocvery (#776)
Add the WithPKCEFromDiscovery option to create a relying party with PKCE
enabled if it is supported when query the discovery endpoint as
discussed in #506.

This only works when creating an OIDC RP which performs a discovery
call. With an OAuth2-only RP, an error is returned as no discovery call
is performed.

Closes #506

### Definition of Ready

- [x] I am happy with the code
- [x] Short description of the feature/issue is added in the pr
description
- [x] PR is linked to the corresponding user story
- [ ] Acceptance criteria are met
- [ ] All open todos and follow ups are defined in a new ticket and
justified
- [ ] Deviations from the acceptance criteria and design are agreed with
the PO and documented.
- [x] No debug or dead code
- [x] My code has no repetitions
- [x] Critical parts are tested automatically
- [x] Where possible E2E tests are implemented
- [x] Documentation/examples are up-to-date
- [x] All non-functional requirements are met
- [ ] Functionality of the acceptance criteria is checked manually on
the dev system.
2025-09-29 08:42:54 +00:00
Livio Spring
adddf0e4b3 refactor: deprecate proprietary key file use for JWT Profile (#801)
While reviewing #750, we noticed that the `KeyFile` struct and
corresponding methods are proprietary to Zitadel and should have never
been part of the pure OIDC library.

This PR deprecates the corresponding parts. For users of Zitadel, the
corresponding code is moved to zitadel/zitadel-go#516

### Definition of Ready

- [x] I am happy with the code
- [x] Short description of the feature/issue is added in the pr
description
- [x] PR is linked to the corresponding user story
- [x] Acceptance criteria are met
- [ ] All open todos and follow ups are defined in a new ticket and
justified
- [ ] Deviations from the acceptance criteria and design are agreed with
the PO and documented.
- [x] No debug or dead code
- [x] My code has no repetitions
- [x] Critical parts are tested automatically
- [ ] Where possible E2E tests are implemented
- [x] Documentation/examples are up-to-date
- [x] All non-functional requirements are met
- [x] Functionality of the acceptance criteria is checked manually on
the dev system.
2025-09-23 08:44:48 +02:00
Brian Joerger
0d50c9369e feat(rp): optional authorized party check (#752)
This PR makes the default Authorized Party check in `rp.VerifyIDToken`
optional by adding an options parameter for dynamic verification
functions. This check is meant to be an optional validation requirement,
so some providers (including GCP) do not adhere to it.

See https://github.com/zitadel/oidc/issues/405 for more context.

Closes https://github.com/zitadel/oidc/issues/405
2025-07-31 08:36:27 +00:00
Marco A.
dbf1a731a9 feat: pass optional logout hint and ui locales to end session request (#774)
### Definition of Ready

- [x] I am happy with the code
- [x] Short description of the feature/issue is added in the pr
description
- [x] PR is linked to the corresponding user story
- [x] Acceptance criteria are met
- [x] All open todos and follow ups are defined in a new ticket and
justified
- [x] Deviations from the acceptance criteria and design are agreed with
the PO and documented.
- [x] No debug or dead code
- [x] My code has no repetitions
- [x] Critical parts are tested automatically
- [x] Where possible E2E tests are implemented
- [x] Documentation/examples are up-to-date
- [x] All non-functional requirements are met
- [x] Functionality of the acceptance criteria is checked manually on
the dev system.

# Context

PR https://github.com/zitadel/oidc/pull/754 has introduced the optional
logout hint and UI locales to the end session request. However, while
working on https://github.com/zitadel/zitadel/pull/10039 , I have
noticed that the integration tests on Zitadel side call
`relying_party.EndSession()` without the possibility of specifying any
logout hint nor ui locales.

This PR adds these 2 parameters to `relying_party.EndSession()`
function.
2025-07-24 21:26:46 +02:00
Mark Laing
c0d0ba9b0f feat: Request aware cookie handling (#753)
* pkg/http: Add `secureCookieFunc` field to CookieHandler.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/http: Add `IsRequestAware` method CookieHandler.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/http: Use `secureCookieFunc` when checking a cookie (if set).

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/http: Error on `SetCookie` if cookie handler is request aware.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/http: Add method to set request aware cookies.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/http: Add function to create a new request aware cookie handler.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/client/rp: Update `trySetStateCookie` function signature.

Use `SetRequestAwareCookie` if the cookie handle is request aware.
This function signature can be updated because it is not exported.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/client/rp: Add `GenerateAndStoreCodeChallengeWithRequest` function.

It's not possible to add a `http.Request` argument to
`GenerateAndStoreCodeChallenge` as this would be a breaking change.
Instead, add a new function that accepts a request argument and call
`SetRequestAwareCookie` here.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/client/rp: Update PKCE logic to pass request if required by cookie handler.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/http: Don't set MaxAge if cookie handler is request aware.

The securecookie field can be nil. Expect the caller to set max age on
the securecookie returned by the secureCookieFunc.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

* pkg/client: Add integration tests for request aware cookie handling.

Adds a new type `cookieSpec` which is accepted as an argument to
`RunAuthorizationCodeFlow`. `TestRelyingPartySession` now runs with
`wrapServer` true/false and with two cookie handlers, one static and one
request aware.

The request aware handler extracts encryption keys from a secret using a
salt from a "login_id" cookie.

Signed-off-by: Mark Laing <mark.laing@canonical.com>

---------

Signed-off-by: Mark Laing <mark.laing@canonical.com>
2025-07-16 11:33:03 +00:00
Jan-Otto Kröpke
21e830e275 feat: exclude OTEL instrumentation via build tag (#770)
* feat: exclude OTEL instrumentation via build tag

* add readme
2025-07-16 11:29:59 +00:00
Steve Ruckdashel
eb98343a65 fix: migrate deprecated io/ioutil.ReadFile to os.ReadFile (#714) 2025-02-21 09:52:02 +00:00
Ayato
3b64e792ed feat(oidc): return defined error when discovery failed (#653)
* feat(oidc): return defined error when discovery failed

* Use errors.Join() to join errors

Co-authored-by: Tim Möhlmann <muhlemmer@gmail.com>

* Remove unnecessary field

Co-authored-by: Tim Möhlmann <muhlemmer@gmail.com>

* Fix order and message

Co-authored-by: Tim Möhlmann <muhlemmer@gmail.com>

* Fix error order

* Simplify error assertion

Co-authored-by: Tim Möhlmann <muhlemmer@gmail.com>

---------

Co-authored-by: Tim Möhlmann <muhlemmer@gmail.com>
2024-09-20 12:33:28 +03:00
David Sharnoff
67688db4c1 fix: client assertions for Okta (#636)
* fix client assertions for Okta

* review feedback
2024-08-26 11:11:01 +03:00
Livio Spring
e5a428d4be feat: support PKCS#8 (#623) 2024-07-09 15:55:50 +02:00
Yuval Marcus
5a84d8c4bc fix: Omit non-standard, empty fields in RefreshTokenRequest when performing a token refresh (#599)
* Add omitempty tags

* Add omitempty to more fields
2024-05-06 08:13:52 +02:00
Yuval Marcus
24d43f538e fix: Handle case where verifier Nonce func is nil (#594)
* Skip nonce check if verifier nonce func is nil

* add unit test
2024-05-02 09:46:12 +02:00
Kotaro Otaka
3512c72f1c fix: to propagate context (#593)
Co-authored-by: Livio Spring <livio.a@gmail.com>
2024-04-22 11:40:21 +00:00
Kotaro Otaka
68d4e08f6d feat: Added the ability to verify ID tokens using the value of id_token_signing_alg_values_supported retrieved from DiscoveryEndpoint (#579)
* feat(rp): to use signing algorithms from discovery configuration (#574)

* feat: WithSigningAlgsFromDiscovery to verify IDTokenVerifier() behavior in RP with
2024-04-16 08:41:31 +00:00
Ethan Heilman
959376bde7 Fixes typos in GoDoc and comments (#591) 2024-04-16 08:18:32 +00:00
Tim Möhlmann
33f8df7eb2 feat(deps): update go-jose to v4 (#588)
This change updates to go-jose v4, which was a new major release.

jose.ParseSigned now expects the supported signing algorithms to be passed, on which we previously did our own check. As they use a dedicated type for this, the slice of string needs to be converted. The returned error also need to be handled in a non-standard way in order to stay compatible.

For OIDC v4 we should use the jose.SignatureAlgorithm  type directly and wrap errors, instead of returned static defined errors.

Closes #583
2024-04-11 18:13:30 +03:00
Jan-Otto Kröpke
06f37f84c1 fix: Fail safe, if optional endpoints are not given (#582) 2024-04-09 13:02:31 +00:00
Célian GARCIA
c89d0ed970 feat: return oidc.Error in case of call token failure (#571) 2024-04-01 13:55:22 +00:00
adlerhurst
565a022e91 Merge branch 'extend-tracing' of https://github.com/zitadel/oidc into extend-tracing 2024-03-14 07:51:35 +01:00
adlerhurst
03f3bc693b fix test 2024-03-14 07:50:29 +01:00
Silvan
0ffd13c780 Merge branch 'main' into extend-tracing 2024-03-13 15:45:19 +01:00
adlerhurst
1b94f796eb move tracer to client,
add tracing in rs, client
2024-03-13 15:45:03 +01:00
Tim Möhlmann
ad79802968 feat: extend token exchange response (#567)
* feat: extend token exchange response

This change adds fields to the token exchange and token claims types.

The `act` claim has been added to describe the actor in case of impersonation or delegation. An actor can be nested in case an obtained token is used as actor token to obtain impersonation or delegation. This allows creating a chain of actors. See [RFC 8693, section 4.1](https://www.rfc-editor.org/rfc/rfc8693#name-act-actor-claim).

The `id_token` field has been added to the Token Exchange response  so an ID Token can be returned along with an access token. This is not specified in RFC 8693, but it allows us be consistent with OpenID responses when the scope `openid` is set, while the requested token type may remain access token.

* allow jwt profile for token exchange client

* add invalid target error
2024-03-13 16:26:09 +02:00
adlerhurst
bdcccc3303 feat(client): tracing in rp 2024-03-06 18:39:27 +01:00
Ayato
5ef597b1db feat(op): Add response_mode: form_post (#551)
* feat(op): Add response_mode: form_post

* Fix to parse the template ahead of time

* Fix to render the template in a buffer

* Remove unnecessary import

* Fix test

* Fix example client setting

* Make sure the client not to reuse the content of the response

* Fix error handling

* Add the response_mode param

* Allow implicit flow in the example app

* feat(rp): allow form_post in code exchange callback handler

---------

Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
2024-03-05 15:04:43 +02:00
Tim Möhlmann
972b8981e5 feat: go 1.22 and slog migration (#557)
This change adds Go 1.22 as a build target and drops support for Go 1.20 and older. The golang.org/x/exp/slog import is migrated to log/slog.

Slog has been part of the Go standard library since Go 1.21. Therefore we are dropping support for older Go versions. This is in line of our support policy of "the latest two Go versions".
2024-02-28 10:44:14 +01:00
Jan-Otto Kröpke
f4bbffb51b feat: Add rp.WithAuthStyle as Option (#546)
* feat: Add rp.WithAuthStyle as Option

* Update integration_test.go

* Update integration_test.go

* Update integration_test.go
2024-02-23 12:18:06 +02:00
Jan-Otto Kröpke
b45072a4c0 fix: Set unauthorizedHandler, if not defined (#547) 2024-02-21 12:17:00 +02:00
Jan-Otto Kröpke
984e31a9e2 feat(rp): Add UnauthorizedHandler (#503)
* RP: Add UnauthorizedHandler

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>

* remove race condition

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>

* Use optional interface

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>

---------

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-01-09 17:24:05 +02:00
Jan-Otto Kröpke
e23b1d4754 fix: Implement dedicated error for RevokeToken (#508)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-01-08 10:01:34 +02:00
Tim Möhlmann
fe3e02b80a feat(rp): client credentials grant (#494)
This change adds Client Credentials grant to the Relying Party.
As specified in [RFC 6749, section 4.4](https://datatracker.ietf.org/doc/html/rfc6749#section-4.4)
2023-12-05 06:40:16 +01:00
Tim Möhlmann
d9487ef77d Merge branch 'next' into next-main 2023-10-12 16:07:49 +03:00
Thomas Hipp
e6e3835362 chore: replace interface{} with any (#448)
This PR replaces all occurances of interface{} with any to be consistent and improve readability.

* example: Replace `interface{}` with `any`

Signed-off-by: Thomas Hipp <thomashipp@gmail.com>

* pkg/client: Replace `interface{}` with `any`

Signed-off-by: Thomas Hipp <thomashipp@gmail.com>

* pkg/crypto: Replace `interface{}` with `any`

Signed-off-by: Thomas Hipp <thomashipp@gmail.com>

* pkg/http: Replace `interface{}` with `any`

Signed-off-by: Thomas Hipp <thomashipp@gmail.com>

* pkg/oidc: Replace `interface{}` with `any`

Signed-off-by: Thomas Hipp <thomashipp@gmail.com>

* pkg/op: Replace `interface{}` with `any`

Signed-off-by: Thomas Hipp <thomashipp@gmail.com>

---------

Signed-off-by: Thomas Hipp <thomashipp@gmail.com>
2023-10-12 12:41:04 +03:00
Tim Möhlmann
0f8a0585bf feat(op): Server interface (#447)
* first draft of a new server interface

* allow any response type

* complete interface docs

* refelct the format from the proposal

* intermediate commit with some methods implemented

* implement remaining token grant type methods

* implement remaining server methods

* error handling

* rewrite auth request validation

* define handlers, routes

* input validation and concrete handlers

* check if client credential client is authenticated

* copy and modify the routes test for the legacy server

* run integration tests against both Server and Provider

* remove unuse ValidateAuthRequestV2 function

* unit tests for error handling

* cleanup tokenHandler

* move server routest test

* unit test authorize

* handle client credentials in VerifyClient

* change code exchange route test

* finish http unit tests

* review server interface docs and spelling

* add withClient unit test

* server options

* cleanup unused GrantType method

* resolve typo comments

* make endpoints pointers to enable/disable them

* jwt profile base work

* jwt: correct the test expect

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2023-09-28 17:30:08 +03:00
Tim Möhlmann
daf82a5e04 chore(deps): migrage jose to go-jose/v3 (#433)
closes #390
2023-09-01 14:33:16 +03:00
Tim Möhlmann
0879c88399 feat: add slog logging (#432)
* feat(op): user slog for logging

integrate with golang.org/x/exp/slog for logging.
provide a middleware for request scoped logging.

BREAKING CHANGES:

1. OpenIDProvider and sub-interfaces get a Logger()
method to return the configured logger;
2. AuthRequestError now takes the complete Authorizer,
instead of only the encoder. So that it may use its Logger() method.
3. RequestError now takes a Logger as argument.

* use zitadel/logging

* finish op and testing
without middleware for now

* minimum go version 1.19

* update go mod

* log value testing only on go 1.20 or later

* finish the RP and example

* ping logging release
2023-08-29 14:07:45 +02:00
Tim Möhlmann
6708ef4c24 feat(rp): return oidc.Tokens on token refresh (#423)
BREAKING CHANGE:
- rename RefreshAccessToken to RefreshToken
- RefreshToken returns *oidc.Tokens instead of *oauth2.Token

This change allows the return of the id_token in an explicit manner,
as part of the oidc.Tokens struct.
The return type is now consistent with the CodeExchange function.

When an id_token is returned, it is verified.
In case no id_token was received,
RefreshTokens will not return an error.

As per specifictation:
https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokenResponse

Upon successful validation of the Refresh Token,
the response body is the Token Response of Section 3.1.3.3
except that it might not contain an id_token.

Closes #364
2023-08-18 14:36:39 +02:00
Diego Parisi
45582b6ee9 feat: delete PKCE cookie after code exchange (#419) 2023-08-14 18:14:24 +03:00
Hugo Hromic
406153a4f4 fix(client/rs): do not error when issuer discovery has no introspection endpoint (#414)
* chore(tests): add basic unit tests for `pkg/client/rs/resource_server.go`
* fix: do not error when issuer discovery has no introspection endpoint
2023-06-23 09:19:58 +02:00
Tim Möhlmann
d01a5c8f91 fix: don't error on invalid i18n tags in discovery (#407)
* reproduce #406

* fix: don't error on invalid i18n tags in discovery

This changes the use of `[]language.Tag` to
`oidc.Locales` in `DiscoveryConfig`.
This should be compatible with callers that use
the `[]language.Tag` .

Locales now implements the `json.Unmarshaler` interface.
With support for json arrays or space seperated strings.
The latter because `UnmarshalText` might have been implicetely called
by the json library before we added UnmarshalJSON.

Fixes: #406
2023-06-09 16:31:44 +02:00
Tim Möhlmann
d5a9bd6d0e feat: generic Userinfo and Introspect functions (#389)
BREAKING CHANGE: rp.Userinfo and rs.Introspect now require
a type parameter.
2023-05-05 12:36:37 +00:00
David Sharnoff
157bc6ceb0 feat: coverage prompt=none, response_mode=fragment (#385) 2023-05-03 12:56:47 +02:00
David Sharnoff
e62473ba71 chore: improve error message when issuer is invalid (#383) 2023-05-03 12:09:19 +02:00
Tim Möhlmann
edf306219f chore(rp): add a custom claims test for VerifyIDToken (#375) 2023-05-02 11:31:30 +02:00
Tim Möhlmann
8dff7ddee0 Merge branch 'main' into main-to-next 2023-04-18 12:32:04 +03:00
David Sharnoff
f0d46593e0 feat: rp.RefreshAccessToken() now may provide an updated IDToken (#365) 2023-04-13 16:37:50 +03:00
Thomas Hipp
312c2a07e2 fix: Only set GrantType once (#353) (#367)
This fixes an issue where, when using the device authorization flow, the
grant type would be set twice. Some OPs don't accept this, and fail when
polling.

With this fix the grant type is only set once, which will make some OPs
happy again.

Fixes #352
2023-04-13 16:04:58 +03:00
Thomas Hipp
c778e8329c feat: Allow modifying request to device authorization endpoint (#356)
* feat: Allow modifying request to device authorization endpoint

This change enables the caller to set URL parameters when calling the
device authorization endpoint.

Fixes #354

* Update device authorization example
2023-04-03 14:40:29 +02:00
Thomas Hipp
1a2db3683f fix: Only set GrantType once (#353)
This fixes an issue where, when using the device authorization flow, the
grant type would be set twice. Some OPs don't accept this, and fail when
polling.

With this fix the grant type is only set once, which will make some OPs
happy again.

Fixes #352
2023-03-29 07:51:10 +00:00