azure-ad-msalazure-app-registrationredirect-uri

Why localhost redirect URI for Azure AD desktop app / MSAL, and how does it work?


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

https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-desktop-app-registration#redirect-uris

As a security best practice, we recommend explicitly setting https://login.microsoftonline.com/common/oauth2/nativeclient or http://localhost as the redirect URI


Solution

  • 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:

    1. obtain an available ephemeral port from the OS
    2. open an exclusive network socket on that port, and listen for the response.
    3. initiate the MSAL process supplying localhost:step1port# as the redirect URI, which opens the system browser, where the user supplies their AAD credentials
    4. once the MSAL auth browser process is complete, then it send the auth token back to localhost:step1port#, which the desktop app is listening on so it can receive the response.
    5. close the localhost socket opened in step 2

    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.