twobotechnologies

Federation · 4 min read

SP-Initiated SSO on .NET: From WIF to Modern Libraries

Short answer

In SP-initiated SSO the application sends the user to the identity provider with an authentication request and validates the response that comes back; Windows Identity Foundation supported this for WS-Federation, not SAML 2.0 protocol, so modern .NET apps use the built-in OpenID Connect or WS-Federation handlers, or a SAML 2.0 library for ASP.NET Core.

Key takeaways

  • SP-initiated flows let the SP bind the response to its own request (InResponseTo, RelayState), which IdP-initiated flows cannot.
  • WIF ships in .NET Framework (System.IdentityModel) and is not part of modern .NET; it never implemented the SAML 2.0 protocol.
  • For new .NET work, prefer OpenID Connect; use a maintained SAML 2.0 library when a partner requires SAML.

Windows Identity Foundation was Microsoft's claims-based identity library for .NET Framework. It made federated sign-in look easy: add some configuration, and your ASP.NET app trusted AD FS. It also caused a lot of confusion, because many people assumed it did SAML 2.0 SSO. It did not, quite. Here is how SP-initiated SSO works and what to use on .NET today.

What is SP-initiated SSO?

The user starts at the application (the service provider), which redirects them to the identity provider with a request, and then validates the IdP's response against that request.

In SAML 2.0 terms:

  1. The user opens https://app.example.com/reports.
  2. The SP creates an AuthnRequest with a unique ID, and sends it to the IdP's SSO URL, usually with the HTTP-Redirect binding (DEFLATE, base64, URL-encode) and a RelayState that remembers where the user was going.
  3. The IdP authenticates the user and posts a Response back to the SP's Assertion Consumer Service URL with the HTTP-POST binding. InResponseTo carries the request's ID.
  4. The SP validates the signature, issuer, audience, recipient, time conditions and InResponseTo, then creates a session and sends the user to the RelayState location.

Paste either message into the SAML Decoder: it inflates Redirect-binding requests and shows the InResponseTo, Destination and condition values of a response.

Why is SP-initiated safer than IdP-initiated?

Because the SP can tie the response to a request it made, which stops unsolicited responses and some login CSRF.

With IdP-initiated SSO the SP receives a response it never asked for, so it cannot check InResponseTo. Attackers can try to replay or inject assertions, or log a victim in to the attacker's account. Many security guides recommend disabling IdP-initiated flows unless an application truly needs them, and adding replay detection on assertion IDs when you keep them.

What did WIF actually support?

WS-Federation passive sign-in and WS-Trust, with SAML 1.1 and 2.0 tokens, but not the SAML 2.0 protocol and its bindings.

This is the source of the confusion. WIF could consume a SAML 2.0 assertion, the token, when it arrived inside a WS-Federation response. It did not generate SAML 2.0 AuthnRequest messages or handle the SAML Web Browser SSO profile. Microsoft published a SAML 2.0 extension as a preview, but it never became a supported release. From .NET Framework 4.5, WIF was folded into the framework itself (System.IdentityModel and System.IdentityModel.Services).

So "SP-initiated with WIF" meant WS-Federation: the app redirected to AD FS with wa=wsignin1.0, wtrealm and wctx, and AD FS posted back a wresult containing a token.

What should I use on .NET today?

OpenID Connect where possible; the WS-Federation handler for existing AD FS apps; a SAML 2.0 library when a partner requires SAML.

Need Option
New app, any modern IdP ASP.NET Core OpenID Connect handler, or Microsoft.Identity.Web for Entra ID
Existing WS-Federation app on AD FS ASP.NET Core WS-Federation handler
Partner requires SAML 2.0 A maintained open-source or commercial SAML 2.0 library for ASP.NET Core
Legacy .NET Framework app Keep WIF running, plan migration; OWIN middleware offers OIDC and WS-Fed
Token validation only Microsoft.IdentityModel libraries (JWT and SAML token handlers)

Whichever library you pick, check that it validates InResponseTo, rejects unsigned assertions, enforces audience and recipient, and has a recent release history.

What are the common SP-initiated mistakes?

Ignoring RelayState validation, skipping InResponseTo, and trusting the wrong signature.

  • An unchecked RelayState can become an open redirect. Only allow relative paths or a known list.
  • Store the request ID with the user's pre-login session and require InResponseTo to match.
  • Verify the signature covers the assertion you actually read; XML signature wrapping attacks hide a second, unsigned assertion.

For federation trust in general, see the federation guide; for AD FS claims, the LDAP attribute store article.

Questions

What is the difference between SP-initiated and IdP-initiated SSO?

In SP-initiated SSO, the user starts at the application, which sends an authentication request to the IdP. In IdP-initiated SSO, the user starts at the IdP portal, which sends an unsolicited response to the application. SP-initiated is safer because the response can be matched to a request.

Does ASP.NET Core support SAML 2.0 out of the box?

No. ASP.NET Core includes OpenID Connect and WS-Federation authentication handlers. For SAML 2.0 you need a third-party library, either open source or commercial.

Sources

Tagged: WIF, .NET, Microsoft, SAML, Single sign-on, AD FS, STS (security token service)

The Twobo Technologies editors write practical explainers on identity and API security and maintain the free tools on this site. Spotted an error or an outdated detail? Email contact@twobotechnologies.com.

Related articles