Browser-grade OAuth login for any Microsoft-federated provider - without a browser.
Project description
Entrance
Your headless entrance to Microsoft Entra.
Browser-grade OAuth login for any Microsoft-federated provider - without a browser.
[!WARNING] For educational and research purposes only. Use it solely against accounts you own or with the explicit authorization of the account/tenant owner. It drives a real sign-in with real credentials - treat the cookie jar and any tokens like passwords. See the Disclaimer below.
About The Project
Plenty of services hand you an OAuth "open this URL in a browser to log in" link and federate the actual authentication to Microsoft Entra. entrance walks that flow for you over pure HTTP - no Playwright, no headless Chromium, no Selenium - and hands back the authorization code (or exchanged tokens). Point it at any authorize URL that ends up at login.microsoftonline.com and it logs in, handles MFA, and returns.
The whole thing is one small module and two dependencies.
How It Works
The trick that makes browserless login actually work against a modern Entra tenant:
- Impersonate Opera, not Chrome. Entra serves a JavaScript-only "Chrome SSO pull" page (un-replayable without a real browser) when it sees a Google Chrome user-agent. Tell it you're Opera - a non-Chrome Chromium - and it serves the plain credential page instead, which is replayable.
- Real browser fingerprint.
curl_cffireplays a genuine browser TLS/JA3 fingerprint, so Entra's edge sees a browser at the wire level. - Replay the login XHRs by hand -
GetCredentialType→login→ "Stay signed in?". For MFA, theSAS/BeginAuth+SAS/EndAuthpair with a TOTP code computed viapyotp. - Intercept the code at the callback redirect - it's read off the
Locationheader and never actually delivered. - Silent reuse. The Microsoft session cookie jar is persisted, so the next run logs in with no password (and no MFA prompt) until it expires.
Features
- 🚪 No browser - pure HTTP, drives
login.microsoftonline.comdirectly - 🌐 Provider-agnostic - give it any OAuth2 authorize URL federated to Entra
- 🔐 Headless MFA - TOTP second factor solved automatically from your authenticator secret
- 🍪 Silent SSO - persisted cookie jar means password-free reruns
- 🎛️ Three return modes - the raw
code, exchangedaccess_token, or just the Microsoft redirect - 📦 Tiny - one module,
curl_cffi+pyotp
Installation
pip install ms-entrance
# or
uv add ms-entrance
The import name is entrance (e.g. from entrance import login). Requires Python 3.10+; curl_cffi and pyotp are pulled in automatically.
Quickstart
from entrance import login
# Intercept the authorization code from any Entra-federated authorize URL
res = login(
"https://provider.example/authorize?client_id=...&state=...&code_challenge=...",
username="you@school.ch",
password="...",
totp_secret="JBSWY3DPEHPK3PXP", # optional - only if the account has TOTP MFA
)
print(res["code"]) # the authorization code (intercepted at the callback)
print(res["callback_url"]) # the full callback URL - built, NOT sent
Exchange the code for tokens - pass a token_url and it does the OAuth exchange for you:
res = login(authorize_url, "you@school.ch", "...",
code_verifier=verifier, token_url="https://provider.example/token")
print(res["access_token"])
Just the Microsoft handoff - stop at the redirect Microsoft issues back to the provider, untouched:
res = login("https://provider.example/", "you@school.ch", "...", ms_redirect=True)
print(res["redirect_url"]) # https://provider.example/?code=...&state=...&session_state=...
Silent reuse - the first call saves .ms_session.json; every call after that skips the password:
login(authorize_url, "you@school.ch", "...") # full login, saves the jar
login(authorize_url) # silent - no password, no MFA
Return Value
| Key | When | What |
|---|---|---|
code |
always | the authorization code |
code_verifier / state |
always | echoed back for your own exchange |
callback_url |
default mode | the redirect_uri?code=…&state=…, built not sent |
access_token / tokens |
when token_url is set |
the exchanged token response |
redirect_url / session_state |
when ms_redirect=True |
the raw Microsoft → provider redirect |
Caveats
- Works only against managed Entra tenants (
login.microsoftonline.com), not third-party federated IdPs (ADFS, Google, etc.). - Push / SMS MFA can't be done headless - only TOTP (authenticator app). Enroll one and pass its Base32 secret.
- Microsoft tweaks its login pages; if a flow breaks, the user-agent or a field name is usually the culprit.
Disclaimer
Entrance is published for educational and research purposes only - to document how OAuth2 / OpenID Connect authorization-code + PKCE flows behave when federated through Microsoft Entra, and how a browserless client negotiates them.
Use it only against accounts you own, or with the explicit authorization of the account or tenant owner. You alone are responsible for your use of it and for complying with Microsoft's terms, your identity provider's terms, your institution's acceptable-use policy, and applicable law. Automating logins to accounts you do not own, evading access controls, or circumventing MFA you were not granted is not the intended use. The software is provided "as is", without warranty of any kind, and the author accepts no liability for misuse. Not affiliated with or endorsed by Microsoft.
License
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ms_entrance-1.0.0.tar.gz.
File metadata
- Download URL: ms_entrance-1.0.0.tar.gz
- Upload date:
- Size: 10.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f752cef76e60a393aaa338decc6e95797b8be43c613edfc823bc585780df4316
|
|
| MD5 |
955798b7112d264bcee29ef0b7f97b40
|
|
| BLAKE2b-256 |
be09ab9e17d23ce6f03afce757e981c3f95bdf098901b3f13b2076dfd40b1b71
|
File details
Details for the file ms_entrance-1.0.0-py3-none-any.whl.
File metadata
- Download URL: ms_entrance-1.0.0-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6928c4a2591ea20da59c099c4498ac69cb4e649faa2a8c31b040ec388971eaa
|
|
| MD5 |
98cc9fd02ea9b6cbb495eebac5488d84
|
|
| BLAKE2b-256 |
e5d76ecd2d70c87dca3d9740fb231da5aebd8991fe5863c1a0573843d8c19145
|