I'm working on a OAuth native application with a loopback interface redirection and am trying to reconcile RFC6749 (The OAuth 2.0 Authorization Framework) with RFC8252 (OAuth 2.0 for Native Apps):
In RFC6749 the specification requires using an absolute URI as the client's redirection endpoint (section 3.1.2):
The redirection endpoint URI MUST be an absolute URI ... The endpoint URI MUST NOT include a fragment component.
However, this appears to have an exception in RFC8252. The specification states that any port may be used for loopback IP redirect URIs (section 7.3):
The authorization server MUST allow any port to be specified at the time of the request for loopback IP redirect URIs, to accommodate clients that obtain an available ephemeral port from the operating system at the time of the request.
And indicates that loopback IP redirect URIs will be supported (Appendix A.):
OAuth servers that support native apps must: ...
- Support loopback IP redirect URIs. This is required to support desktop operating systems.
RFC8252 also provides registration clarification (section 8.4):
Authorization servers MUST require clients to register their complete redirect URI (including the path component) and reject authorization requests that specify a redirect URI that doesn't exactly match the one that was registered; the exception is loopback redirects, where an exact match is required except for the port URI component.
Thus, I understand that the correct behavior for an OAuth 2.0 authorization server with a native app client is to:
- Require the registration of a loopback redirect URI (ie.
http://127.0.0.1/oauth2redirect/example-provider
), perhaps with wildcard port:*
- On a GET request to
/authorize
, match theredirect_uri
request parameter with the registered URI, but allow any port to be specified (ie.http://127.0.0.1:61023/oauth2redirect/example-provider
would be accepted)
Am I missing anything here? Is this the expected behavior for an OAuth 2.0 authorization server with a registered native application?
CodePudding user response:
For desktop apps the usual thing is to find a free port at runtime, then spin up a loopback server at a URL such as http://localhost:8000, without any path. This listener exists for only one reason, to receive a login response.
In theory you can register http://localhost
as the redirect URI for the client and any port will work, though I have very rarely seen that supported by Authorization Servers.
Here is some example code of mine to show how that looks.My app therefore registers three specific redirect URLs, for ports 8001-8003.
You are right that only exact URLs should be registered, to avoid open redirector vulnerabilities. The RFC8252 behaviour for desktop apps and multiple ports is a special case. You can either choose to use it, or register multiple redirect URIs with different ports.
Another option is to use Private URI Schemes for desktop apps (personally I prefer this). Mobile apps should use HTTPS redirect URIs, as the most secure option - this is required for financial-grade apps.