question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Breaking changes in OpenIddict 4.0 impacting how URIs are handled

See original GitHub issue

Initially planned for OpenIddict 5.0, the modifications introducing behavior changes in the URIs handling will finally ship as part of 4.0.

Before detailing these changes, here’s a bit of history to understand the motivations for changing the existing behavior:

  • OpenIddict 1.x/2.x exclusively used ASP.NET Core’s PathString primitive type as a way to represent endpoint addresses. As a consequence, only relative paths were supported and, as required by PathString’s constructor, paths had to start with a leading / (e.g /connect/authorize). This was simple and unambiguous, but sadly quite limited.

  • As part of the ASP.NET Core decoupling, OpenIddict 3.0 stopped using the ASP.NET Core-specific PathString type to represent endpoint addresses and started using System.Uri, which was also a good opportunity to support absolute URIs (e.g if you want to separate the userinfo endpoint from your main authorization server, you can simply call options.SetUserinfoEndpointUris("https://api.domain.com/userinfo") with an absolute URI and OpenIddict will return it as-is in the discovery document (userinfo requests won’t be served by OpenIddict itself as the host of the specified address will differ from the one in the received requests).

To avoid a breaking change at the time, the same semantics as the ones defined by PathString were preserved, so things worked similarly as in previous versions: relative URIs still had to start with a leading / (otherwise the request were simply ignored by OpenIddict) and none of the typical canonicalization rules of URIs applied (e.g you couldn’t start your endpoint address with ./ or have .. in them).

Retrospectively, not adopting that breaking change was not a good idea, as relative System.Uri instances starting with a / don’t have the same meaning as PathString (that always starts with a /): unlike PathString, a leading / in a System.Uri always indicates a site/root-relative URI, which is the typical behavior you also see with URLs in a HTML document (e.g if the current URL is https://domain.com/path/, a relative link to document.html will point to https://domain.com/path/document.html while a relative link to /document.html will point to https://domain.com/document.html).

These inconsistencies contributed to confusing users - who often asked why things didn’t work when they used options.SetAuthorizationEndpointUris("authorize") instead of options.SetAuthorizationEndpointUris("/authorize") - so the behavior in OpenIddict 4.0 will change to fully embrace the System.Uri rules for relative URIs and reduce the confusion:

Relative endpoint URIs will now follow the System.Uri rules

Two cases exist:

HttpRequest.PathBase is equal to string.Empty

It’s the most common scenario. In this case, the application root is http://domain.com/ so if you keep using /connect/authorize as an endpoint address, nothing will change compared to 3.x as the resulting absolute URI will be http://domain.com/connect/authorize.

If you decide to use ./connect/authorize or connect/authorize or even ../connect/authorize, the resulting address will still be http://domain.com/connect/authorize.

HttpRequest.PathBase is not equal to string.Empty

It’s typically the case when using IIS virtual application paths or when using certain ASP.NET Core middleware (built-in or not) that change HttpRequest.PathBase to a specific value (e.g for multi-tenant scenarios). In this case, the application root is http://domain.com/pathbase so if you use /endpoint (which is a root-relative address), the resulting address will be http://domain.com/endpoint and not http://domain.com/path/endpoint.

To keep the same final address, users will have to change the endpoint address to endpoint or ./endpoint instead of /endpoint.

As a positive consequence, users are now able to specify relative addresses that are outside the current application. For instance, an HttpRequest.PathBase of /tenantA/authorization-server with an address of ../userinfo will result in an absolute URI of http://domain.com/tenantA/userinfo, which can be useful when the userinfo API is not in the same application as the authorization server.

Absolute endpoint URIs returned by the configuration endpoint (.well-known/openid-configuration) no longer uses the OpenIddictServerOptions.Issuer property as the base URI to compute absolute URIs.

In 4.0, the absolute endpoints URIs returned by .well-known/openid-configuration will no longer use OpenIddictServerOptions.Issuer as the base URI. Instead, the computed value of HttpRequest.Scheme + Uri.SchemeDelimiter + HttpRequest.Host + HttpRequest.PathBase - which was already used when no explicit OpenIddictServerOptions.Issuer was set - will always be used, so that the addresses reflect the request details exposed by ASP.NET Core.

I took a look at the community projects that sponsor OpenIddict and here’s how it will affect them:

Feel free if you have any question or remark.

Issue Analytics

  • State:closed
  • Created 9 months ago
  • Reactions:1
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
kevinchaletcommented, Dec 6, 2022

Note: if you want to give it a try, the new behavior is present in the 4.0 rc1 bits, whose nightly builds can be found on the MyGet feed. It should land on NuGet.org very soon.

0reactions
kevinchaletcommented, Mar 8, 2023

Non-default ports are supported. If you’re seeing a different behavior, open a support ticket (sponsors-only).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Breaking changes in OpenIddict 4.0 impacting how URIs ...
Hey @maliming,. 4.0.0-rc1.22607.41 was just pushed to NuGet.org. You can find the main changes in the release notes: ...
Read more >
Migrate to OpenIddict 4.0
OpenIddict 4.0 introduces a behavior change that affects how endpoint URIs are computed and resolved. For more information about this change, read Breaking...
Read more >
OpenIddict 4.0 general availability | Kévin Chalet's blog
While OpenIddict 4.0 comes with some breaking changes, the migration process should be fairly easy. To help users with this process, ...
Read more >
Introducing the OpenIddict client - Kévin Chalet's blog
NET 4.x/OWIN, an OpenID Connect middleware maintained by Microsoft. ... that affect OpenIddict users that the team is unwilling to fix.
Read more >
Modules/OpenIddict | Documentation Center | ABP.IO
OpenIddict module provides an integration with the OpenIddict which provides advanced authentication features like single sign-on, single log-out, and API ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found