Welcome to the Streamlit community, and thanks for the super detailed question!
It could be possible that forwarding the authenticated Windows user identity from IIS to Streamlit via HTTP headers is tricky due to how IIS modules process requests. According to community discussions, Streamlit apps behind reverse proxies (including IIS) often can’t access custom headers injected by IIS, especially those set after authentication, because Streamlit’s Python backend only sees headers present at the time the WebSocket connection is established—not those added later or by outbound rules. Even hardcoded custom headers may not appear due to how IIS and ARR handle header forwarding and the timing of authentication modules. This is a known limitation, and several users have reported similar issues when trying to pass Windows Auth info to backend apps like Streamlit via headers or server variables, with the headers not surfacing in st.context.headers or previous workarounds like _get_websocket_headers() (source, source).
Though I’m not entirely certain, it might be that the only robust way to achieve seamless SSO with user identity in Streamlit is to use a reverse proxy that can inject headers before the WebSocket handshake, or to use a custom authentication component that leverages cookies or tokens set by IIS. Some users have had success with Nginx (not IIS) by ensuring headers are set before the WebSocket upgrade, but IIS’s module order and ARR’s handling may prevent this. There doesn’t seem to be a battle-tested, out-of-the-box solution for IIS + Windows Auth + Streamlit that meets your requirements without additional login prompts or architectural changes. If you want to share your IIS config and Streamlit version, the community might be able to suggest more targeted workarounds! And if anyone else has cracked this, please jump in and share your insights! ![]()
Sources: