Skip to content

Configurable redirect URI and free loopback port for browser login - #125

Open
balcsida wants to merge 2 commits into
osodevops:mainfrom
balcsida:feat/configurable-redirect-uri
Open

balcsida wants to merge 2 commits into
osodevops:mainfrom
balcsida:feat/configurable-redirect-uri

Conversation

@balcsida

Copy link
Copy Markdown

The browser (authorization code + PKCE) login hardcoded the redirect URI http://localhost:8400/callback and listened only on 127.0.0.1:8400. That ruled out public client apps whose registered redirect URI has no path, such as Microsoft's own "Microsoft Graph Command Line Tools" app (14d82eec-204b-4c2f-b7e8-296a70dab67e, registered http://localhost), because the identity platform ignores the port of a localhost redirect URI but matches the path exactly. It also failed when port 8400 was busy, and missed the callback when the browser resolved localhost to ::1.

Behaviour changes:

  • --redirect-uri, TEAMS_CLI_REDIRECT_URI and the profile's redirect_uri select the redirect URI for auth login, auth consent-url and auth doctor, with the same precedence as the client and tenant IDs. A delegated login saves the flag value to the profile with the IDs; the env value is used but not saved.
  • The login listens on every loopback address the URI's host resolves to (both 127.0.0.1 and ::1 for localhost) and accepts the callback on any path. A URI must be http and point at localhost or a loopback IP literal; anything else is invalid input (exit 2) before a browser opens. A port held by another process is still an error, since that process could receive the authorization code.
  • A URI without a port gets a free port from the OS at each login, as MSAL does, and that port-bearing URI goes into both the authorize URL and the token exchange. An explicit port is sent exactly as given.
  • The default is now http://localhost/callback on a free port instead of http://localhost:8400/callback, so a busy port 8400 no longer blocks login. Registrations with http://localhost:8400/callback keep working because the port is ignored.

Usage:

# Microsoft's public Graph command line app, registered http://localhost (no path)
teams auth login --client-id 14d82eec-204b-4c2f-b7e8-296a70dab67e --tenant-id <tenant-id> --redirect-uri http://localhost

# Built-in OSO app: nothing to pass, a free port is picked
teams auth login

Review guide:

  • 27057f8 the configurable URI: resolve_redirect_uri and remember_registration in config.rs, loopback_addrs and bind_loopback in auth_code_pkce.rs.
  • d8960cd the free port: bind_loopback now returns the shared port, redirect_uri_with_port rewrites the URI, and the authorize URL is built after binding.

Testing: unit tests cover URI validation, the shared free port across listeners, the busy-port error and the URI rewrite; CLI tests cover the flag, env, profile and default for consent-url and doctor, and that a bad URI exits 2 for both the browser and device code flows. Which URIs the two apps accept was checked read-only against the authorize endpoint with prompt=none (a registered URI gets a login_required redirect, an unregistered one gets an inline error): the OSO app accepts http://localhost/callback on any port, the Microsoft app accepts http://localhost on any port, and neither accepts 127.0.0.1. No live login was run from this branch; the first real sign-in is the remaining check.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant