I have seen it recommended to use http://localhost as the redirect URI for Azure AD app registrations for desktop apps. Can anyway explain why localhost is used, how this actually works (technical details), and what makes this secure?
For example, we have a 3rd party desktop app which integrates with Excel to pull data from our ERP via web services. It uses Azure AD app registration to authenticate as the current user using MSAL and retrieve data on their behalf, and it requires localhost to be setup as the redirect URI.
When the Azure AD token is sent back to the generic localhost redirect URI, how does it know to return back to the app that originated the request, vs. going to a locally hosted website, or any other locally installed app that is using MSAL or listening on port 80?
I understand that localhost is the recommended setting from various article I have read, but I'm just trying to understand why and how it works.
References
https://learn.microsoft.com/en-us/azure/active-directory/develop/reply-url
A redirect URI, or reply URL, is the location where the authorization server sends the user once the app has been successfully authorized and granted an authorization code or access token. The authorization server sends the code or token to the redirect URI, so it's important you register the correct location as part of the app registration process
As a security best practice, we recommend explicitly setting https://login.microsoftonline.com/common/oauth2/nativeclient or http://localhost as the redirect URI
I finally found the answer after reading through MANY articles which led me to RFC 8252. Even though just http://localhost is specified in the Azure AD app redirect URI list, it really allows redirecting on any localhost port (per RFC 8252 Section 7.3) which states "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".
So then the Windows desktop app would:
REFERENCES:
https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
Native apps that are able to open a port on the loopback network
interface without needing special permissions (typically, those on
desktop operating systems) can use the loopback interface to receive
the OAuth redirect.Loopback redirect URIs use the "http" scheme and are constructed with the loopback IP literal and whatever port the client is listening on. That is, "http://127.0.0.1:{port}/{path}" for IPv4, and "http://[::1]:{port}/{path}" for IPv6. An example redirect using the IPv4 loopback interface with a randomly assigned port:
http://127.0.0.1:51004/oauth2redirect/example-provider
An example redirect using the IPv6 loopback interface with a randomly assigned port:
http://[::1]:61023/oauth2redirect/example-provider
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.Clients SHOULD NOT assume that the device supports a particular
version of the Internet Protocol. It is RECOMMENDED that clients
attempt to bind to the loopback interface using both IPv4 and IPv6
and use whichever is available.
https://datatracker.ietf.org/doc/html/rfc8252#appendix-B.3
Both traditional and Universal Windows Platform (UWP) apps can
perform authorization requests in the user's browser. Traditional
apps typically use a loopback redirect to receive the authorization
response, and listening on the loopback interface is allowed by
default firewall rules. When creating the loopback network socket,
apps SHOULD set the "SO_EXCLUSIVEADDRUSE" socket option to prevent
other apps binding to the same socket.