Understanding WS-Federation: A modern primer for an obsolete protocol

Scott Brady
Scott Brady
WS-Federation

Why the hell am I writing about WS-Federation in 2024? Well, it turns out a lot of organizations, especially Microsoft shops with ADFS running on-premises, still default to using WS-Federation, and I’ve had customers come to me asking how to support it or even asking, “What is WS-Federation anyway? I can’t find anything about it on Google!”.

Unfortunately, most of my favorite articles and resources about WS-Federation have long since disappeared from the internet. So, in their honor and to keep the knowledge accessible, I’ve written a modern primer on the WS-Federation protocol, focussing on the core Single Sign-On (SSO) parts that are still in use, rather than any of the WS-Trust features of WS-Federation.

In this article, you will learn the basics of how the WS-Federation works, what the various protocol messages look like, and some of its security limitations. By the end of this article, you should be in a position to integrate your application (a Relying Party) with a WS-Federation identity provider (a Security Token Service) and debug any issues along the way.

This article combines my experience using WS-Federation in SharePoint, ASP.NET 4.x, and ASP.NET Core applications with information from the 2009 WS-Federation 1.2 specification.

What is WS-Federation?

WS-Federation is a Single Sign-On (SSO) protocol for web applications. There’s more to it than that, but that’s the most useful part of it. It’s part of the wider, thankfully defunct, suite of WS-* standards, but we try not to talk about those.

Created and popularized by Microsoft, WS-Federation saw initial popularity thanks to its use in ADFS (Active Directory Federation Services). However, ADFS and its successor Azure AD (now Entra ID 🤢) now support both SAML 2.0 and OpenID Connect, SSO protocols with increased features, better security profiles, and widespread support beyond the Microsoft ecosystem.

As a protocol, it is very similar to protocols such as SAML 2.0 and OpenID Connect. In fact, WS-Federation even borrows various constructs from SAML, albeit with a much smaller feature set (a lot of SAML is long dead, but the core protocol and constructs still have their uses). Much like these alternatives, WS-Federation uses a request & response format, with the user being redirected via the browser to a central location to authenticate for SSO.

How does WS-Federation work?

WS-Federation works in much the same way as SAML 2.0 and OpenID Connect. You have a web application that wants to know who the user is and a central service in charge of user authentication and issuing security assertions about the user.

With WS-Federation, the requesting application is known as the Relying Party (RP), and the central service is known as the Security Token Service (STS).

The Relying Party redirects the user to the Security Token Service, requesting a security token for the current user. Once the user authenticates themselves at the Security Token Service, they are redirected back to the Relying Party along with the requested security token. The Relying Party can then validate the token, understand the user’s identity, and start a session for that user.

TODO

Relying Parties

The Relying Party is the web application that wants to use Single Sign-On (SSO). It wants to know who the user is and how they authenticated without asking the user for their credentials, with the end goal of starting a session.

Relying Parties must be known to the Security Token Service beforehand and have a registered realm and reply URL.

The realm is a URI that identifies the Relying Party. It is the unique identifier for the Relying Party within that Security Token Service. It is pretty much the same as OpenID Connect’s client ID or SAML’s entity ID.

The reply URL is where the Security Token Service can redirect the user after authentication along with any security data. It’s where the Relying Party will be listening for a response from the STS. The rely URL is the same as OpenID Connect’s return URI or the location on a SAML AssertionConsumerService.

Security Token Service (STS)

The Security Token Service is the identity provider that can authenticate users and issue tokens. It is the central service that enables single sign-on. Users will likely have an SSO session within the Security Token Service, saving them from having to enter their credentials every time an application wants to know their identity.

The Security Token Service must also know about the Relying Party in advance. WS-Federation is typically used when federating sign-on between businesses, for example, using your own SSO solution to log into a SaaS app, rather than your organization’s employees needing to have yet another set of credentials. The Security Token Service is your identity provider.

To use the Security Token Service, a Relying Party must know its:

  • Entity ID: the URI of the Security Token Service; its unique identifier.
  • Signature validation key: the public key that should be used to validate any signatures created by the Security Token Service. This could be the raw public key or a key within an X.509 certificate.
  • Security Token Service endpoint: a URL within the STS responsible for single sign-on. The Relying Party will redirect the user to this endpoint along with a WS-Federation sign-in request.

WS-Federation metadata

Like SAML and OpenID Connect, WS-Federation Security Token Services can host a metadata document so that Relying Parties can automatically configure themselves to use the Security Token Service. This also means that Relying Parties can automatically load in new key material, simplifying key rotation.

WS-Federation’s metadata document extends SAML 2.0’s metadata document, using the urn:oasis:names:tc:SAML:2.0:metadata namespace and the http://docs.oasis-open.org/wsfed/federation/200706 namespace.

It is a public document that contains data anyone should be allowed to know. Don’t let anyone tell you otherwise.

In the world of Azure AD and ADFS, this metadata document is usually hosted on /federationmetadata/2007-06/federationmetadata.xml.

If you’re using Azure AD, I’ve found that this metadata is available on https://login.microsoftonline.com, https://login.microsoftonline.com, and https://sts.windows.net. I’m not sure what that’s about.

WS-Federation does support metadata documents for Relying Parties; however, I have never seen one of these used in the wild.

Example WS-Federation Security Token Service metadata

Below is an abbreviated example of your typical WS-Federation metadata document for a Security Token Service generated by Azure AD. I’ve removed the signature element for readability. Check out the full metadata document for an unedited version.

<EntityDescriptor
  ID="_e25357e0-5b7b-42fd-99c3-6769d181b255"
  entityID="https://sts.windows.net/ff191596-4ffd-4c77-93e7-6167a5756569/"
  xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
  <RoleDescriptor
    xsi:type="fed:SecurityTokenServiceType"
    protocolSupportEnumeration="http://docs.oasis-open.org/wsfed/federation/200706"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:fed="http://docs.oasis-open.org/wsfed/federation/200706">
    <KeyDescriptor use="signing">
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <X509Data>
          <X509Certificate>MIIC/jCCAeagAwIBAgIJAOCJOVRxNKcNMA0GCSqGSIb3DQEBCwUAMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwHhcNMjMwODI4MjAwMjQwWhcNMjgwODI4MjAwMjQwWjAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz/w+5U4eZwenXYnEgt2rCN+753YQ7RN8ykiNprNiLl4ilpwAGLWF1cssoRflsSiBVZcCSwUzUwsifG7sbRq9Vc8RFs72Gg0AUwPsJFUqNttMg3Ot+wTqsZtE5GNSBUSqnI+iWoZfjw+uLsS0u4MfzP8Fpkd+rzRlifuIAYK8Ffi1bldkszeBzQbBZbXFwiw5uTf8vEAkH/IAdB732tQAsNXpWWYDV74nKAiwLlDS5FWVs2S2T+MPNAg28MLxYfRhW2bUpd693inxI8WTSLRncouzMImJF4XeMG2ZRZ0z/KJra/uzzMCLbILtpnLA95ysxWw+4ygm3MxN2iBM2IaJeQIDAQABoyEwHzAdBgNVHQ4EFgQU/wzRzxsifMCz54SZ3HuF4P4jtzowDQYJKoZIhvcNAQELBQADggEBACaWlbJTObDai8+wmskHedKYb3FCfTwvH/sCRsygHIeDIi23CpoWeKt5FwXsSeqDMd0Hb6IMtYDG5rfGvhkNfunt3sutK0VpZZMNdSBmIXaUx4mBRRUsG4hpeWRrHRgTnxweDDVw4Mv+oYCmpY7eZ4SenISkSd/4qrXzFaI9NeZCY7Jg9vg1bev+NaUtD3C4As6GQ+mN8Rm2NG9vzgTDlKf4Wb5Exy7u9dMW1TChiy28ieVkETKdqwXcbhqM8GOLBUFicdmgP2y9aDGjb89BuaeoHJCGpWWCi3UZth14clVzC6p7ZD6fFx5tKMOL/hQvs3ugGtvFDWCsvcT8bB84RO8=</X509Certificate>
        </X509Data>
      </KeyInfo>
    </KeyDescriptor>
    <fed:SecurityTokenServiceEndpoint>
      <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:Address>https://login.microsoftonline.com/ff191596-4ffd-4c77-93e7-6167a5756569/wsfed</wsa:Address>
      </wsa:EndpointReference>
    </fed:SecurityTokenServiceEndpoint>
    <fed:PassiveRequestorEndpoint>
      <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:Address>https://login.microsoftonline.com/ff191596-4ffd-4c77-93e7-6167a5756569/wsfed</wsa:Address>
      </wsa:EndpointReference>
    </fed:PassiveRequestorEndpoint>
  </RoleDescriptor>
</EntityDescriptor>

WS-Federation Security Token Service metadata format

WS-Federation’s federation metadata uses SAML 2.0’s metadata namespace for the standard EntitiesDescriptor and EntityDescriptor elements. This descriptor will contain the entity ID (entityID) of the Security Token Service.

<EntityDescriptor
  ID="_e25357e0-5b7b-42fd-99c3-6769d181b255"
  entityID="https://sts.windows.net/ff191596-4ffd-4c77-93e7-6167a5756569/"
  xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
    <!-- content -->
</EntityDescriptor>

The base element used to describe a WS-Federation Security Token Service is RoleDescriptor. This must have a protocolSupportEnumeration attribute set http://docs.oasis-open.org/wsfed/federation/200706 and a type attribute of SecurityTokenServiceType.

<RoleDescriptor
  xsi:type="fed:SecurityTokenServiceType"
  protocolSupportEnumeration="http://docs.oasis-open.org/wsfed/federation/200706" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:fed="http://docs.oasis-open.org/wsfed/federation/200706">
    <!-- content -->
</RoleDescriptor>

You then have a SAML KeyDescriptor with key info from XMLDSig, describing the key you can use to validate SAML tokens created by the Security Token Service.

<KeyDescriptor use="signing">
  <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
    <X509Data>
      <X509Certificate>MIIC/jCCAeagAwIBAgIJAOCJOVRxNKcNMA0GCSqGSIb3DQEBCwUAMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwHhcNMjMwODI4MjAwMjQwWhcNMjgwODI4MjAwMjQwWjAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz/w+5U4eZwenXYnEgt2rCN+753YQ7RN8ykiNprNiLl4ilpwAGLWF1cssoRflsSiBVZcCSwUzUwsifG7sbRq9Vc8RFs72Gg0AUwPsJFUqNttMg3Ot+wTqsZtE5GNSBUSqnI+iWoZfjw+uLsS0u4MfzP8Fpkd+rzRlifuIAYK8Ffi1bldkszeBzQbBZbXFwiw5uTf8vEAkH/IAdB732tQAsNXpWWYDV74nKAiwLlDS5FWVs2S2T+MPNAg28MLxYfRhW2bUpd693inxI8WTSLRncouzMImJF4XeMG2ZRZ0z/KJra/uzzMCLbILtpnLA95ysxWw+4ygm3MxN2iBM2IaJeQIDAQABoyEwHzAdBgNVHQ4EFgQU/wzRzxsifMCz54SZ3HuF4P4jtzowDQYJKoZIhvcNAQELBQADggEBACaWlbJTObDai8+wmskHedKYb3FCfTwvH/sCRsygHIeDIi23CpoWeKt5FwXsSeqDMd0Hb6IMtYDG5rfGvhkNfunt3sutK0VpZZMNdSBmIXaUx4mBRRUsG4hpeWRrHRgTnxweDDVw4Mv+oYCmpY7eZ4SenISkSd/4qrXzFaI9NeZCY7Jg9vg1bev+NaUtD3C4As6GQ+mN8Rm2NG9vzgTDlKf4Wb5Exy7u9dMW1TChiy28ieVkETKdqwXcbhqM8GOLBUFicdmgP2y9aDGjb89BuaeoHJCGpWWCi3UZth14clVzC6p7ZD6fFx5tKMOL/hQvs3ugGtvFDWCsvcT8bB84RO8=</X509Certificate>
    </X509Data>
  </KeyInfo>
</KeyDescriptor>

In this case, the public key is part of an X.509 certificate.

For a Security Token Service, you must define a SecurityTokenServiceEndpoint. This is the endpoint for handling WS-Federation sign-in requests. It can also contain a PassiveRequestorEndpoint, which is often the same endpoint.

<fed:SecurityTokenServiceEndpoint>
  <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <wsa:Address>https://login.microsoftonline.com/ff191596-4ffd-4c77-93e7-6167a5756569/wsfed</wsa:Address>
  </wsa:EndpointReference>
</fed:SecurityTokenServiceEndpoint>

A metadata document is usually signed and can contain descriptors for other protocols supported by that entity. For example, a single EntityDescriptor may contain a RoleDescriptor for a WS-Federation STS and an IDPSSODescriptor for a SAML Identity Provider (IdP).

There are many more features available in WS-Federation’s metadata, including metadata for Relying Parties, more types of endpoints, and claim type information (ClaimTypesOffered), but the above is the minimum required for a modern WS-Federation implementation. Much like SAML, many features in WS-Federation didn’t really find an audience, and only the core SSO functionality remains in use.

To learn more about the SAML 2.0 metadata that WS-Federation extends, check out my Pluralsight course: Getting Started with SAML 2.0.

WS-Federation for Single Sign-On (SSO)

WS-Federation’s Single Sign-On flow is very similar to the HTTP Redirect & Post bindings in SAML 2.0 and the implicit flow in OAuth and OpenID Connect.

You start with a sign-in request, included in a redirect from the Relying Party to the Security Token Service, and finish with a security token in a redirect back to the Relying Party. In its most basic form, there is no server-to-server communication. Everything happens within the browser.

WS-Federation sign-in request

A WS-Federation sign-in request consists of the action you are trying to perform (sign-in) and the unique identifier (URI) of the Relying Party making the request. This data is included in the query string when redirecting the user to the Security Token Service.

Here's an example of a sign-in request (URL decoded for readability):

HTTP/1.1 302 Found
Location: https://login.microsoftonline.com/ff191596-4ffd-4c77-93e7-6167a5756569/wsfed
  ?wa=wsignin1.0
  &wtrealm=spn:993d198b-c95f-4aaa-9f10-04a3fec6d1f1

Sign-in requests have two required parameters:

  • wa - the action you are performing. This must always be wsignin1.0 when signing in (requesting a security token).
  • wtrealm - the URI of the Relying Party. This must be known to the STS before you can make a request.

The Security Token Service will validate that it knows the Relying Party before authenticating the user and generating a Security Token Service.

There are other parameters available that can be useful depending on your use case. Officially, these are optional; however, I recommend always using the wreply and wctx fields.

  • wreply - where the response should be sent. This is a URL in the Relying Party that is listening for security token responses.
  • wctx - the context. An opaque value created by the Relying Party that is included in the request and echoed back by the Security Token Service in the security token response. Do not use this for round-tripping data. Instead, use a random value bound to that browser session (via a cookie) to act as basic protection against Cross-Site Request Forgery (CSRF). This allows the Relying Party to perform some validation that the response it received was created for the request it made. This is similar to SAML’s relay state and OAuth & OpenID Connect’s state parameter. It’s not very effective.
  • wfresh - the freshness requirement. The allowed number of minutes since the user last authenticated. The STS cannot issue a token that expires after this time. If this is set to 0, the STS must reauthenticate the user before issuing a token (similar to OpenID Connect’s prompt=login and SAML’s ForceAuthn functionality).
  • wct - timestamp used in freshness check(?)
  • wauth - the level of authentication the user must have met. If the user has authenticated to a lower standard, then the STS must authenticate them. This is similar to OpenID Connect’s acr_values and SAML’s RequestedAuthenticationContext.
  • whr - the upstream identity provider that the STS should use to authenticate the user. You can use this to bypass home realm discovery (HRD), where the user would otherwise be asked to choose how they want to authenticate (for example, with a local username & password vs. external social media authentication).

My recommended minimum sign-in request would look something like this (URL decoded for readability):

HTTP/1.1 302 Found
Location: https://login.microsoftonline.com/ff191596-4ffd-4c77-93e7-6167a5756569/wsfed
  ?wa=wsignin1.0
  &wtrealm=spn:993d198b-c95f-4aaa-9f10-04a3fec6d1f1
  &wreply=https://localhost:5000/signin-wsfed
  &wctx=Glfvq5tYM1SuhoR2A5yPeAMrXrfSrdNibfrqqGnVD1A

You can also send sign-in requests as a POST, but there is not much benefit to this – nothing in the request is confidential, and all of the parameters will still go via the browser.

WS-Federation security token response

Once the user has authenticated (explicitly or using an existing session at the Security Token Service), they are redirected back to the Relying Party with a security token response. This response is typically sent as a form post containing the action (sign-in), the security token itself, and the context (assuming you sent one in your request).

While you could redirect using a GET request with this data in the query string, the security token itself is fairly large and will likely break the maximum URL length of a server or browser. The security token will also likely contain personal information, and while query strings are encrypted using TLS, they are usually logged in plaintext by web servers. This would mean you are writing unencrypted PII (Personally Identifiable Information) to disk.

A form post is a common workaround for posting data via the browser while also redirecting to another page. This is done by returning an auto-submitting HTML form. Here’s an example adapted from the OpenID Connect specification:

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Cache-Control: no-cache, no-store
Pragma: no-cache

<html>
 <head><title>Submit This Form</title></head>
 <body onload="javascript:document.forms[0].submit()">
  <form method="post" action="https://localhost:5000/signin-wsfed">
    <input type="hidden" name="wa" value="wsignin1.0"/>
    <input type="hidden" name="wresult" value="%3Ct%3ARequestSecurityTokenResponse+xmlns%3At%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F02%2Ftrust%22%3E%3Ct%3ALifetime%3E%3Cwsu%3ACreated+xmlns%3Awsu%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-utility-1.0.xsd%22%3E2023-12-03T20%3A21%3A08.019Z%3C%2Fwsu%3ACreated%3E%3Cwsu%3AExpires+xmlns%3Awsu%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-utility-1.0.xsd%22%3E2023-12-03T21%3A26%3A08.019Z%3C%2Fwsu%3AExpires%3E%3C%2Ft%3ALifetime%3E%3Cwsp%3AAppliesTo+xmlns%3Awsp%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2004%2F09%2Fpolicy%22%3E%3Cwsa%3AEndpointReference+xmlns%3Awsa%3D%22http%3A%2F%2Fwww.w3.org%2F2005%2F08%2Faddressing%22%3E%3Cwsa%3AAddress%3Espn%3A993d198b-c95f-4aaa-9f10-04a3fec6d1f1%3C%2Fwsa%3AAddress%3E%3C%2Fwsa%3AEndpointReference%3E%3C%2Fwsp%3AAppliesTo%3E%3Ct%3ARequestedSecurityToken%3E%3CAssertion+ID%3D%22_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%22+IssueInstant%3D%222023-12-03T20%3A26%3A08.075Z%22+Version%3D%222.0%22+xmlns%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Aassertion%22%3E%3CIssuer%3Ehttps%3A%2F%2Fsts.windows.net%2Fff191596-4ffd-4c77-93e7-6167a5756569%2F%3C%2FIssuer%3E%3CSignature+xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23%22%3E%3CSignedInfo%3E%3CCanonicalizationMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F10%2Fxml-exc-c14n%23%22+%2F%3E%3CSignatureMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256%22+%2F%3E%3CReference+URI%3D%22%23_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%22%3E%3CTransforms%3E%3CTransform+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23enveloped-signature%22+%2F%3E%3CTransform+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F10%2Fxml-exc-c14n%23%22+%2F%3E%3C%2FTransforms%3E%3CDigestMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmlenc%23sha256%22+%2F%3E%3CDigestValue%3EdQ%2FzsfzPdxfHXdLxEKWa9NmXPgypO2Sd0RL8dtX3zR8%3D%3C%2FDigestValue%3E%3C%2FReference%3E%3C%2FSignedInfo%3E%3CSignatureValue%3EpjMgTvdDYLQg2iy6brrEgfTO5UJSoIhwpDqT%2FYLXz5tgzBix1v5BFRPXWLtjYLqZ%2FO4YUSKLymGWzQj1ZJjkDcNl9XSN9rsYhV6DnzzP7nkAhRfGkI1aafAwbJzHENlU5acsrbrWDMn3GglfW7%2Fg1%2FR6bMxRZrchK466s%2Bjie1M7R6JawlnOAOMGyb4Exw1faceDi%2FP98nYktnOI7JZDK60Rxf1LQdUVKbrhJ0IXa4nqikFAbNRO14VGTMfq0WEuTcQgIEmDArpflkqglO1%2F9JE7YxN203LKALD4VFiOMgOjQhp%2BeJ865GpFJW2ObgHRnrfMqh3VOTbKQL5E8jxlWQ%3D%3D%3C%2FSignatureValue%3E%3CKeyInfo%3E%3CX509Data%3E%3CX509Certificate%3EMIIC%2FTCCAeWgAwIBAgIIUd7j%2FOIahkYwDQYJKoZIhvcNAQELBQAwLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDAeFw0yMzExMDExNjAzMjdaFw0yODExMDExNjAzMjdaMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzZMJFMHQcoR8sE%2BLf%2FwLEJtaKvPuuW%2FNxeen%2FSPeOuZv%2BGy3SKIeJ9IHATQVXVZbv0rLDQABOQt9IsvKWXIK7OChQ6CZd3dgxqoHyZA4Eh5wVAMAeQzWzLOL9XBV0m3wfXIjSE4Zw6S26MM8eJ1UW066gOoBaUKzuQIbCVrMrhJ%2B7%2Bmd8kjhGZTwC%2Bo7Rq4ZzGDbggJuk%2FTUbQ%2BBu9by6FZJZJJNeZ90iHnrsk4eyC8WvSbUBRC%2FvBt5HGDKIfCfb2HqDVvBJgkHgjpMwb5wPKC9T2U1YXN5iG2obhn9wDeSFYgyZOrd1XMKyLiJTfT35zQWilZpxMei4fIxFykkVAgMBAAGjITAfMB0GA1UdDgQWBBRNcCE3HDX%2BHOJOu%2FbKfLYoSX3%2F0jANBgkqhkiG9w0BAQsFAAOCAQEAExns169MDr1dDNELYNK0JDjPUA6GR50jqfc%2Bxa2KOljeXErOdihSvKgDS%2FvnDN6fjNNZuOMDyr6jjLvRsT0jVWzf%2FB6v92FrPRa%2Frv3urGXvW5am3BZyVPipirbiolMTuork95G7y7imftK7117uHcMq3D8f4fxscDiDXgjEEZqjkuzYDGLaVWGJqpv5xE4w%2BK4o2uDwmEIeIX%2BrI1MEVucS2vsvraOrjqjHwc3KrzuVRSsOU7YVHyUhku%2B7oOrB4tYrVbYYgwd6zXnkdouVPqOX9wTkc9iTmbDP%2BrfkhdadLxU%2BhmMyMuCJKgkZbWKFES7ce23jfTMbpqoHB4pgtQ%3D%3D%3C%2FX509Certificate%3E%3C%2FX509Data%3E%3C%2FKeyInfo%3E%3C%2FSignature%3E%3CSubject%3E%3CNameID+Format%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Anameid-format%3Apersistent%22%3EI2jEtI4v3fuD9662-VvgmjE30UFNK2FmdcLRVN05giQ%3C%2FNameID%3E%3CSubjectConfirmation+Method%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Acm%3Abearer%22+%2F%3E%3C%2FSubject%3E%3CConditions+NotBefore%3D%222023-12-03T20%3A21%3A08.019Z%22+NotOnOrAfter%3D%222023-12-03T21%3A26%3A08.019Z%22%3E%3CAudienceRestriction%3E%3CAudience%3Espn%3A993d198b-c95f-4aaa-9f10-04a3fec6d1f1%3C%2FAudience%3E%3C%2FAudienceRestriction%3E%3C%2FConditions%3E%3CAttributeStatement%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Ftenantid%22%3E%3CAttributeValue%3Eff191596-4ffd-4c77-93e7-6167a5756569%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Fobjectidentifier%22%3E%3CAttributeValue%3Ec29b8387-074f-4870-a917-3ef4a25452e7%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F05%2Fidentity%2Fclaims%2Fname%22%3E%3CAttributeValue%3Euser%40scottbrady91.onmicrosoft.com%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Fdisplayname%22%3E%3CAttributeValue%3ETest+user%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Fidentityprovider%22%3E%3CAttributeValue%3Ehttps%3A%2F%2Fsts.windows.net%2Fff191596-4ffd-4c77-93e7-6167a5756569%2F%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fclaims%2Fauthnmethodsreferences%22%3E%3CAttributeValue%3Ehttp%3A%2F%2Fschemas.microsoft.com%2Fws%2F2008%2F06%2Fidentity%2Fauthenticationmethod%2Fpassword%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3C%2FAttributeStatement%3E%3CAuthnStatement+AuthnInstant%3D%222023-12-03T20%3A25%3A56.157Z%22%3E%3CAuthnContext%3E%3CAuthnContextClassRef%3Eurn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Aac%3Aclasses%3APassword%3C%2FAuthnContextClassRef%3E%3C%2FAuthnContext%3E%3C%2FAuthnStatement%3E%3C%2FAssertion%3E%3C%2Ft%3ARequestedSecurityToken%3E%3Ct%3ARequestedAttachedReference%3E%3CSecurityTokenReference+d3p1%3ATokenType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLV2.0%22+xmlns%3Ad3p1%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-wssecurity-secext-1.1.xsd%22+xmlns%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-secext-1.0.xsd%22%3E%3CKeyIdentifier+ValueType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLID%22%3E_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%3C%2FKeyIdentifier%3E%3C%2FSecurityTokenReference%3E%3C%2Ft%3ARequestedAttachedReference%3E%3Ct%3ARequestedUnattachedReference%3E%3CSecurityTokenReference+d3p1%3ATokenType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLV2.0%22+xmlns%3Ad3p1%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-wssecurity-secext-1.1.xsd%22+xmlns%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-secext-1.0.xsd%22%3E%3CKeyIdentifier+ValueType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLID%22%3E_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%3C%2FKeyIdentifier%3E%3C%2FSecurityTokenReference%3E%3C%2Ft%3ARequestedUnattachedReference%3E%3Ct%3ATokenType%3Ehttp%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLV2.0%3C%2Ft%3ATokenType%3E%3Ct%3ARequestType%3Ehttp%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F02%2Ftrust%2FIssue%3C%2Ft%3ARequestType%3E%3Ct%3AKeyType%3Ehttp%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F05%2Fidentity%2FNoProofKey%3C%2Ft%3AKeyType%3E%3C%2Ft%3ARequestSecurityTokenResponse%3E"/>
  </form>
 </body>
</html>

As soon as the browser loads this HTML, the form will automatically submit, redirecting the user back to the Relying Party along with a request body containing the form data.

POST /signin-wsfed HTTP/1.1
Host: localhost:5000
Content-Type: application/x-www-form-urlencoded

wa=wsignin1.0
&wresult=%3Ct%3ARequestSecurityTokenResponse+xmlns%3At%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F02%2Ftrust%22%3E%3Ct%3ALifetime%3E%3Cwsu%3ACreated+xmlns%3Awsu%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-utility-1.0.xsd%22%3E2023-12-03T20%3A21%3A08.019Z%3C%2Fwsu%3ACreated%3E%3Cwsu%3AExpires+xmlns%3Awsu%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-utility-1.0.xsd%22%3E2023-12-03T21%3A26%3A08.019Z%3C%2Fwsu%3AExpires%3E%3C%2Ft%3ALifetime%3E%3Cwsp%3AAppliesTo+xmlns%3Awsp%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2004%2F09%2Fpolicy%22%3E%3Cwsa%3AEndpointReference+xmlns%3Awsa%3D%22http%3A%2F%2Fwww.w3.org%2F2005%2F08%2Faddressing%22%3E%3Cwsa%3AAddress%3Espn%3A993d198b-c95f-4aaa-9f10-04a3fec6d1f1%3C%2Fwsa%3AAddress%3E%3C%2Fwsa%3AEndpointReference%3E%3C%2Fwsp%3AAppliesTo%3E%3Ct%3ARequestedSecurityToken%3E%3CAssertion+ID%3D%22_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%22+IssueInstant%3D%222023-12-03T20%3A26%3A08.075Z%22+Version%3D%222.0%22+xmlns%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Aassertion%22%3E%3CIssuer%3Ehttps%3A%2F%2Fsts.windows.net%2Fff191596-4ffd-4c77-93e7-6167a5756569%2F%3C%2FIssuer%3E%3CSignature+xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23%22%3E%3CSignedInfo%3E%3CCanonicalizationMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F10%2Fxml-exc-c14n%23%22+%2F%3E%3CSignatureMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256%22+%2F%3E%3CReference+URI%3D%22%23_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%22%3E%3CTransforms%3E%3CTransform+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23enveloped-signature%22+%2F%3E%3CTransform+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F10%2Fxml-exc-c14n%23%22+%2F%3E%3C%2FTransforms%3E%3CDigestMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmlenc%23sha256%22+%2F%3E%3CDigestValue%3EdQ%2FzsfzPdxfHXdLxEKWa9NmXPgypO2Sd0RL8dtX3zR8%3D%3C%2FDigestValue%3E%3C%2FReference%3E%3C%2FSignedInfo%3E%3CSignatureValue%3EpjMgTvdDYLQg2iy6brrEgfTO5UJSoIhwpDqT%2FYLXz5tgzBix1v5BFRPXWLtjYLqZ%2FO4YUSKLymGWzQj1ZJjkDcNl9XSN9rsYhV6DnzzP7nkAhRfGkI1aafAwbJzHENlU5acsrbrWDMn3GglfW7%2Fg1%2FR6bMxRZrchK466s%2Bjie1M7R6JawlnOAOMGyb4Exw1faceDi%2FP98nYktnOI7JZDK60Rxf1LQdUVKbrhJ0IXa4nqikFAbNRO14VGTMfq0WEuTcQgIEmDArpflkqglO1%2F9JE7YxN203LKALD4VFiOMgOjQhp%2BeJ865GpFJW2ObgHRnrfMqh3VOTbKQL5E8jxlWQ%3D%3D%3C%2FSignatureValue%3E%3CKeyInfo%3E%3CX509Data%3E%3CX509Certificate%3EMIIC%2FTCCAeWgAwIBAgIIUd7j%2FOIahkYwDQYJKoZIhvcNAQELBQAwLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDAeFw0yMzExMDExNjAzMjdaFw0yODExMDExNjAzMjdaMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzZMJFMHQcoR8sE%2BLf%2FwLEJtaKvPuuW%2FNxeen%2FSPeOuZv%2BGy3SKIeJ9IHATQVXVZbv0rLDQABOQt9IsvKWXIK7OChQ6CZd3dgxqoHyZA4Eh5wVAMAeQzWzLOL9XBV0m3wfXIjSE4Zw6S26MM8eJ1UW066gOoBaUKzuQIbCVrMrhJ%2B7%2Bmd8kjhGZTwC%2Bo7Rq4ZzGDbggJuk%2FTUbQ%2BBu9by6FZJZJJNeZ90iHnrsk4eyC8WvSbUBRC%2FvBt5HGDKIfCfb2HqDVvBJgkHgjpMwb5wPKC9T2U1YXN5iG2obhn9wDeSFYgyZOrd1XMKyLiJTfT35zQWilZpxMei4fIxFykkVAgMBAAGjITAfMB0GA1UdDgQWBBRNcCE3HDX%2BHOJOu%2FbKfLYoSX3%2F0jANBgkqhkiG9w0BAQsFAAOCAQEAExns169MDr1dDNELYNK0JDjPUA6GR50jqfc%2Bxa2KOljeXErOdihSvKgDS%2FvnDN6fjNNZuOMDyr6jjLvRsT0jVWzf%2FB6v92FrPRa%2Frv3urGXvW5am3BZyVPipirbiolMTuork95G7y7imftK7117uHcMq3D8f4fxscDiDXgjEEZqjkuzYDGLaVWGJqpv5xE4w%2BK4o2uDwmEIeIX%2BrI1MEVucS2vsvraOrjqjHwc3KrzuVRSsOU7YVHyUhku%2B7oOrB4tYrVbYYgwd6zXnkdouVPqOX9wTkc9iTmbDP%2BrfkhdadLxU%2BhmMyMuCJKgkZbWKFES7ce23jfTMbpqoHB4pgtQ%3D%3D%3C%2FX509Certificate%3E%3C%2FX509Data%3E%3C%2FKeyInfo%3E%3C%2FSignature%3E%3CSubject%3E%3CNameID+Format%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Anameid-format%3Apersistent%22%3EI2jEtI4v3fuD9662-VvgmjE30UFNK2FmdcLRVN05giQ%3C%2FNameID%3E%3CSubjectConfirmation+Method%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Acm%3Abearer%22+%2F%3E%3C%2FSubject%3E%3CConditions+NotBefore%3D%222023-12-03T20%3A21%3A08.019Z%22+NotOnOrAfter%3D%222023-12-03T21%3A26%3A08.019Z%22%3E%3CAudienceRestriction%3E%3CAudience%3Espn%3A993d198b-c95f-4aaa-9f10-04a3fec6d1f1%3C%2FAudience%3E%3C%2FAudienceRestriction%3E%3C%2FConditions%3E%3CAttributeStatement%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Ftenantid%22%3E%3CAttributeValue%3Eff191596-4ffd-4c77-93e7-6167a5756569%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Fobjectidentifier%22%3E%3CAttributeValue%3Ec29b8387-074f-4870-a917-3ef4a25452e7%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F05%2Fidentity%2Fclaims%2Fname%22%3E%3CAttributeValue%3Euser%40scottbrady91.onmicrosoft.com%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Fdisplayname%22%3E%3CAttributeValue%3ETest+user%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Fidentityprovider%22%3E%3CAttributeValue%3Ehttps%3A%2F%2Fsts.windows.net%2Fff191596-4ffd-4c77-93e7-6167a5756569%2F%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fclaims%2Fauthnmethodsreferences%22%3E%3CAttributeValue%3Ehttp%3A%2F%2Fschemas.microsoft.com%2Fws%2F2008%2F06%2Fidentity%2Fauthenticationmethod%2Fpassword%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3C%2FAttributeStatement%3E%3CAuthnStatement+AuthnInstant%3D%222023-12-03T20%3A25%3A56.157Z%22%3E%3CAuthnContext%3E%3CAuthnContextClassRef%3Eurn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Aac%3Aclasses%3APassword%3C%2FAuthnContextClassRef%3E%3C%2FAuthnContext%3E%3C%2FAuthnStatement%3E%3C%2FAssertion%3E%3C%2Ft%3ARequestedSecurityToken%3E%3Ct%3ARequestedAttachedReference%3E%3CSecurityTokenReference+d3p1%3ATokenType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLV2.0%22+xmlns%3Ad3p1%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-wssecurity-secext-1.1.xsd%22+xmlns%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-secext-1.0.xsd%22%3E%3CKeyIdentifier+ValueType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLID%22%3E_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%3C%2FKeyIdentifier%3E%3C%2FSecurityTokenReference%3E%3C%2Ft%3ARequestedAttachedReference%3E%3Ct%3ARequestedUnattachedReference%3E%3CSecurityTokenReference+d3p1%3ATokenType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLV2.0%22+xmlns%3Ad3p1%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-wssecurity-secext-1.1.xsd%22+xmlns%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-secext-1.0.xsd%22%3E%3CKeyIdentifier+ValueType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLID%22%3E_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%3C%2FKeyIdentifier%3E%3C%2FSecurityTokenReference%3E%3C%2Ft%3ARequestedUnattachedReference%3E%3Ct%3ATokenType%3Ehttp%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLV2.0%3C%2Ft%3ATokenType%3E%3Ct%3ARequestType%3Ehttp%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F02%2Ftrust%2FIssue%3C%2Ft%3ARequestType%3E%3Ct%3AKeyType%3Ehttp%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F05%2Fidentity%2FNoProofKey%3C%2Ft%3AKeyType%3E%3C%2Ft%3ARequestSecurityTokenResponse%3E

Responses have two required parameters:

  • wa – the action performed. This must always be wsignin1.0 when signing in (requesting a security token) and match the wa parameter from your request.
  • wresult – containing a RequestSecurityTokenResponse element

And the following optional parameters:

  • wctx – the echoed context. This must be identical to the one from the original request. As I mentioned, validating this and binding it to the browser via a cookie allows you to prevent basic Cross-Site Request Forgery (CSRF) attacks.
  • wresultptr – a pointer to the resulting RequestSecurityTokenResponse, allowing you to retrieve the response without it going via the browser. I’ve personally never seen this used.

So, using the best practice request you saw earlier, you would expect the response to echo back the same context value:

POST /signin-wsfed HTTP/1.1
Host: localhost:5000
Content-Type: application/x-www-form-urlencoded

wa=wsignin1.0
&wresult=%3Ct%3ARequestSecurityTokenResponse+xmlns%3At%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F02%2Ftrust%22%3E%3Ct%3ALifetime%3E%3Cwsu%3ACreated+xmlns%3Awsu%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-utility-1.0.xsd%22%3E2023-12-03T20%3A21%3A08.019Z%3C%2Fwsu%3ACreated%3E%3Cwsu%3AExpires+xmlns%3Awsu%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-utility-1.0.xsd%22%3E2023-12-03T21%3A26%3A08.019Z%3C%2Fwsu%3AExpires%3E%3C%2Ft%3ALifetime%3E%3Cwsp%3AAppliesTo+xmlns%3Awsp%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2004%2F09%2Fpolicy%22%3E%3Cwsa%3AEndpointReference+xmlns%3Awsa%3D%22http%3A%2F%2Fwww.w3.org%2F2005%2F08%2Faddressing%22%3E%3Cwsa%3AAddress%3Espn%3A993d198b-c95f-4aaa-9f10-04a3fec6d1f1%3C%2Fwsa%3AAddress%3E%3C%2Fwsa%3AEndpointReference%3E%3C%2Fwsp%3AAppliesTo%3E%3Ct%3ARequestedSecurityToken%3E%3CAssertion+ID%3D%22_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%22+IssueInstant%3D%222023-12-03T20%3A26%3A08.075Z%22+Version%3D%222.0%22+xmlns%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Aassertion%22%3E%3CIssuer%3Ehttps%3A%2F%2Fsts.windows.net%2Fff191596-4ffd-4c77-93e7-6167a5756569%2F%3C%2FIssuer%3E%3CSignature+xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23%22%3E%3CSignedInfo%3E%3CCanonicalizationMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F10%2Fxml-exc-c14n%23%22+%2F%3E%3CSignatureMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256%22+%2F%3E%3CReference+URI%3D%22%23_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%22%3E%3CTransforms%3E%3CTransform+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23enveloped-signature%22+%2F%3E%3CTransform+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F10%2Fxml-exc-c14n%23%22+%2F%3E%3C%2FTransforms%3E%3CDigestMethod+Algorithm%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmlenc%23sha256%22+%2F%3E%3CDigestValue%3EdQ%2FzsfzPdxfHXdLxEKWa9NmXPgypO2Sd0RL8dtX3zR8%3D%3C%2FDigestValue%3E%3C%2FReference%3E%3C%2FSignedInfo%3E%3CSignatureValue%3EpjMgTvdDYLQg2iy6brrEgfTO5UJSoIhwpDqT%2FYLXz5tgzBix1v5BFRPXWLtjYLqZ%2FO4YUSKLymGWzQj1ZJjkDcNl9XSN9rsYhV6DnzzP7nkAhRfGkI1aafAwbJzHENlU5acsrbrWDMn3GglfW7%2Fg1%2FR6bMxRZrchK466s%2Bjie1M7R6JawlnOAOMGyb4Exw1faceDi%2FP98nYktnOI7JZDK60Rxf1LQdUVKbrhJ0IXa4nqikFAbNRO14VGTMfq0WEuTcQgIEmDArpflkqglO1%2F9JE7YxN203LKALD4VFiOMgOjQhp%2BeJ865GpFJW2ObgHRnrfMqh3VOTbKQL5E8jxlWQ%3D%3D%3C%2FSignatureValue%3E%3CKeyInfo%3E%3CX509Data%3E%3CX509Certificate%3EMIIC%2FTCCAeWgAwIBAgIIUd7j%2FOIahkYwDQYJKoZIhvcNAQELBQAwLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDAeFw0yMzExMDExNjAzMjdaFw0yODExMDExNjAzMjdaMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzZMJFMHQcoR8sE%2BLf%2FwLEJtaKvPuuW%2FNxeen%2FSPeOuZv%2BGy3SKIeJ9IHATQVXVZbv0rLDQABOQt9IsvKWXIK7OChQ6CZd3dgxqoHyZA4Eh5wVAMAeQzWzLOL9XBV0m3wfXIjSE4Zw6S26MM8eJ1UW066gOoBaUKzuQIbCVrMrhJ%2B7%2Bmd8kjhGZTwC%2Bo7Rq4ZzGDbggJuk%2FTUbQ%2BBu9by6FZJZJJNeZ90iHnrsk4eyC8WvSbUBRC%2FvBt5HGDKIfCfb2HqDVvBJgkHgjpMwb5wPKC9T2U1YXN5iG2obhn9wDeSFYgyZOrd1XMKyLiJTfT35zQWilZpxMei4fIxFykkVAgMBAAGjITAfMB0GA1UdDgQWBBRNcCE3HDX%2BHOJOu%2FbKfLYoSX3%2F0jANBgkqhkiG9w0BAQsFAAOCAQEAExns169MDr1dDNELYNK0JDjPUA6GR50jqfc%2Bxa2KOljeXErOdihSvKgDS%2FvnDN6fjNNZuOMDyr6jjLvRsT0jVWzf%2FB6v92FrPRa%2Frv3urGXvW5am3BZyVPipirbiolMTuork95G7y7imftK7117uHcMq3D8f4fxscDiDXgjEEZqjkuzYDGLaVWGJqpv5xE4w%2BK4o2uDwmEIeIX%2BrI1MEVucS2vsvraOrjqjHwc3KrzuVRSsOU7YVHyUhku%2B7oOrB4tYrVbYYgwd6zXnkdouVPqOX9wTkc9iTmbDP%2BrfkhdadLxU%2BhmMyMuCJKgkZbWKFES7ce23jfTMbpqoHB4pgtQ%3D%3D%3C%2FX509Certificate%3E%3C%2FX509Data%3E%3C%2FKeyInfo%3E%3C%2FSignature%3E%3CSubject%3E%3CNameID+Format%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Anameid-format%3Apersistent%22%3EI2jEtI4v3fuD9662-VvgmjE30UFNK2FmdcLRVN05giQ%3C%2FNameID%3E%3CSubjectConfirmation+Method%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Acm%3Abearer%22+%2F%3E%3C%2FSubject%3E%3CConditions+NotBefore%3D%222023-12-03T20%3A21%3A08.019Z%22+NotOnOrAfter%3D%222023-12-03T21%3A26%3A08.019Z%22%3E%3CAudienceRestriction%3E%3CAudience%3Espn%3A993d198b-c95f-4aaa-9f10-04a3fec6d1f1%3C%2FAudience%3E%3C%2FAudienceRestriction%3E%3C%2FConditions%3E%3CAttributeStatement%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Ftenantid%22%3E%3CAttributeValue%3Eff191596-4ffd-4c77-93e7-6167a5756569%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Fobjectidentifier%22%3E%3CAttributeValue%3Ec29b8387-074f-4870-a917-3ef4a25452e7%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F05%2Fidentity%2Fclaims%2Fname%22%3E%3CAttributeValue%3Euser%40scottbrady91.onmicrosoft.com%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Fdisplayname%22%3E%3CAttributeValue%3ETest+user%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fidentity%2Fclaims%2Fidentityprovider%22%3E%3CAttributeValue%3Ehttps%3A%2F%2Fsts.windows.net%2Fff191596-4ffd-4c77-93e7-6167a5756569%2F%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3CAttribute+Name%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fclaims%2Fauthnmethodsreferences%22%3E%3CAttributeValue%3Ehttp%3A%2F%2Fschemas.microsoft.com%2Fws%2F2008%2F06%2Fidentity%2Fauthenticationmethod%2Fpassword%3C%2FAttributeValue%3E%3C%2FAttribute%3E%3C%2FAttributeStatement%3E%3CAuthnStatement+AuthnInstant%3D%222023-12-03T20%3A25%3A56.157Z%22%3E%3CAuthnContext%3E%3CAuthnContextClassRef%3Eurn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Aac%3Aclasses%3APassword%3C%2FAuthnContextClassRef%3E%3C%2FAuthnContext%3E%3C%2FAuthnStatement%3E%3C%2FAssertion%3E%3C%2Ft%3ARequestedSecurityToken%3E%3Ct%3ARequestedAttachedReference%3E%3CSecurityTokenReference+d3p1%3ATokenType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLV2.0%22+xmlns%3Ad3p1%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-wssecurity-secext-1.1.xsd%22+xmlns%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-secext-1.0.xsd%22%3E%3CKeyIdentifier+ValueType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLID%22%3E_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%3C%2FKeyIdentifier%3E%3C%2FSecurityTokenReference%3E%3C%2Ft%3ARequestedAttachedReference%3E%3Ct%3ARequestedUnattachedReference%3E%3CSecurityTokenReference+d3p1%3ATokenType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLV2.0%22+xmlns%3Ad3p1%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-wssecurity-secext-1.1.xsd%22+xmlns%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2F2004%2F01%2Foasis-200401-wss-wssecurity-secext-1.0.xsd%22%3E%3CKeyIdentifier+ValueType%3D%22http%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLID%22%3E_aa6dc647-5e82-448f-8bea-74a0a1ec0e00%3C%2FKeyIdentifier%3E%3C%2FSecurityTokenReference%3E%3C%2Ft%3ARequestedUnattachedReference%3E%3Ct%3ATokenType%3Ehttp%3A%2F%2Fdocs.oasis-open.org%2Fwss%2Foasis-wss-saml-token-profile-1.1%23SAMLV2.0%3C%2Ft%3ATokenType%3E%3Ct%3ARequestType%3Ehttp%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F02%2Ftrust%2FIssue%3C%2Ft%3ARequestType%3E%3Ct%3AKeyType%3Ehttp%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2005%2F05%2Fidentity%2FNoProofKey%3C%2Ft%3AKeyType%3E%3C%2Ft%3ARequestSecurityTokenResponse%3E
&wctx=Glfvq5tYM1SuhoR2A5yPeAMrXrfSrdNibfrqqGnVD1A

Example WS-Federation security token

This is a formatted example of a WS-Federation security token that contains a SAML 2.0 assertion.

<t:RequestSecurityTokenResponse xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
  <t:Lifetime>
    <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2023-12-03T20:21:08.019Z</wsu:Created>
    <wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2023-12-03T21:26:08.019Z</wsu:Expires>
  </t:Lifetime>
  <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
    <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:Address>spn:993d198b-c95f-4aaa-9f10-04a3fec6d1f1</wsa:Address>
    </wsa:EndpointReference>
  </wsp:AppliesTo>
  <t:RequestedSecurityToken>
    <Assertion ID="_aa6dc647-5e82-448f-8bea-74a0a1ec0e00" IssueInstant="2023-12-03T20:26:08.075Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
      <Issuer>https://sts.windows.net/ff191596-4ffd-4c77-93e7-6167a5756569/</Issuer>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
          <Reference URI="#_aa6dc647-5e82-448f-8bea-74a0a1ec0e00">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <DigestValue>dQ/zsfzPdxfHXdLxEKWa9NmXPgypO2Sd0RL8dtX3zR8=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>pjMgTvdDYLQg2iy6brrEgfTO5UJSoIhwpDqT/YLXz5tgzBix1v5BFRPXWLtjYLqZ/O4YUSKLymGWzQj1ZJjkDcNl9XSN9rsYhV6DnzzP7nkAhRfGkI1aafAwbJzHENlU5acsrbrWDMn3GglfW7/g1/R6bMxRZrchK466s jie1M7R6JawlnOAOMGyb4Exw1faceDi/P98nYktnOI7JZDK60Rxf1LQdUVKbrhJ0IXa4nqikFAbNRO14VGTMfq0WEuTcQgIEmDArpflkqglO1/9JE7YxN203LKALD4VFiOMgOjQhp eJ865GpFJW2ObgHRnrfMqh3VOTbKQL5E8jxlWQ==</SignatureValue>
        <KeyInfo>
          <X509Data>
            <X509Certificate>MIIC/TCCAeWgAwIBAgIIUd7j/OIahkYwDQYJKoZIhvcNAQELBQAwLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDAeFw0yMzExMDExNjAzMjdaFw0yODExMDExNjAzMjdaMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzZMJFMHQcoR8sE Lf/wLEJtaKvPuuW/Nxeen/SPeOuZv Gy3SKIeJ9IHATQVXVZbv0rLDQABOQt9IsvKWXIK7OChQ6CZd3dgxqoHyZA4Eh5wVAMAeQzWzLOL9XBV0m3wfXIjSE4Zw6S26MM8eJ1UW066gOoBaUKzuQIbCVrMrhJ 7 md8kjhGZTwC o7Rq4ZzGDbggJuk/TUbQ Bu9by6FZJZJJNeZ90iHnrsk4eyC8WvSbUBRC/vBt5HGDKIfCfb2HqDVvBJgkHgjpMwb5wPKC9T2U1YXN5iG2obhn9wDeSFYgyZOrd1XMKyLiJTfT35zQWilZpxMei4fIxFykkVAgMBAAGjITAfMB0GA1UdDgQWBBRNcCE3HDX HOJOu/bKfLYoSX3/0jANBgkqhkiG9w0BAQsFAAOCAQEAExns169MDr1dDNELYNK0JDjPUA6GR50jqfc xa2KOljeXErOdihSvKgDS/vnDN6fjNNZuOMDyr6jjLvRsT0jVWzf/B6v92FrPRa/rv3urGXvW5am3BZyVPipirbiolMTuork95G7y7imftK7117uHcMq3D8f4fxscDiDXgjEEZqjkuzYDGLaVWGJqpv5xE4w K4o2uDwmEIeIX rI1MEVucS2vsvraOrjqjHwc3KrzuVRSsOU7YVHyUhku 7oOrB4tYrVbYYgwd6zXnkdouVPqOX9wTkc9iTmbDP rfkhdadLxU hmMyMuCJKgkZbWKFES7ce23jfTMbpqoHB4pgtQ==</X509Certificate>
          </X509Data>
        </KeyInfo>
      </Signature>
      <Subject>
        <NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">I2jEtI4v3fuD9662-VvgmjE30UFNK2FmdcLRVN05giQ</NameID>
        <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" />
      </Subject>
      <Conditions NotBefore="2023-12-03T20:21:08.019Z" NotOnOrAfter="2023-12-03T21:26:08.019Z">
        <AudienceRestriction>
          <Audience>spn:993d198b-c95f-4aaa-9f10-04a3fec6d1f1</Audience>
        </AudienceRestriction>
      </Conditions>
      <AttributeStatement>
        <Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
          <AttributeValue>ff191596-4ffd-4c77-93e7-6167a5756569</AttributeValue>
        </Attribute>
        <Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
          <AttributeValue>c29b8387-074f-4870-a917-3ef4a25452e7</AttributeValue>
        </Attribute>
        <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
          <AttributeValue>[email protected]</AttributeValue>
        </Attribute>
        <Attribute Name="http://schemas.microsoft.com/identity/claims/displayname">
          <AttributeValue>Test user</AttributeValue>
        </Attribute>
        <Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
          <AttributeValue>https://sts.windows.net/ff191596-4ffd-4c77-93e7-6167a5756569/</AttributeValue>
        </Attribute>
        <Attribute Name="http://schemas.microsoft.com/claims/authnmethodsreferences">
          <AttributeValue>http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password</AttributeValue>
        </Attribute>
      </AttributeStatement>
      <AuthnStatement AuthnInstant="2023-12-03T20:25:56.157Z">
        <AuthnContext>
          <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
        </AuthnContext>
      </AuthnStatement>
    </Assertion>
  </t:RequestedSecurityToken>
  <t:RequestedAttachedReference>
    <SecurityTokenReference
      d3p1:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
      xmlns:d3p1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
      xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_aa6dc647-5e82-448f-8bea-74a0a1ec0e00</KeyIdentifier>
    </SecurityTokenReference>
  </t:RequestedAttachedReference>
  <t:RequestedUnattachedReference>
    <SecurityTokenReference
      d3p1:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
      xmlns:d3p1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
      xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_aa6dc647-5e82-448f-8bea-74a0a1ec0e00</KeyIdentifier>
    </SecurityTokenReference>
  </t:RequestedUnattachedReference>
  <t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</t:TokenType>
  <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
  <t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
</t:RequestSecurityTokenResponse>

WS-Federation security token format using a SAML assertion

WS-Federation responds with a RequestSecurityTokenResponse element, which is something that comes from the world of WS-Trust. The response element can be wrapped in a SOAP Envelope element; however, this is rare with WS-Federation implementations that are still in use.

The RequestSecurityTokenResponse element itself does not contain much data that is useful to modern applications; you’re mostly interested in the security token embedded within it. Besides the usual Created and Expires elements, it also describes the security token format and if any further authentication mechanisms are required. For example, the above response’s TokenType of http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0 tells you that this response contains a SAML 2.0 assertion.

SAML tokens in WS-Federation

For the majority of remaining WS-Federation implementations, i.e., Active Directory, Azure AD (now Entra ID), the security token itself will be a SAML 2.0 assertion.

<Assertion
  ID="_aa6dc647-5e82-448f-8bea-74a0a1ec0e00"
  IssueInstant="2023-12-03T20:26:08.075Z"
  Version="2.0"
  xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
  <Issuer>https://sts.windows.net/ff191596-4ffd-4c77-93e7-6167a5756569/</Issuer>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
      <Reference URI="#_aa6dc647-5e82-448f-8bea-74a0a1ec0e00">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
        <DigestValue>dQ/zsfzPdxfHXdLxEKWa9NmXPgypO2Sd0RL8dtX3zR8=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>pjMgTvdDYLQg2iy6brrEgfTO5UJSoIhwpDqT/YLXz5tgzBix1v5BFRPXWLtjYLqZ/O4YUSKLymGWzQj1ZJjkDcNl9XSN9rsYhV6DnzzP7nkAhRfGkI1aafAwbJzHENlU5acsrbrWDMn3GglfW7/g1/R6bMxRZrchK466s jie1M7R6JawlnOAOMGyb4Exw1faceDi/P98nYktnOI7JZDK60Rxf1LQdUVKbrhJ0IXa4nqikFAbNRO14VGTMfq0WEuTcQgIEmDArpflkqglO1/9JE7YxN203LKALD4VFiOMgOjQhp eJ865GpFJW2ObgHRnrfMqh3VOTbKQL5E8jxlWQ==</SignatureValue>
    <KeyInfo>
      <X509Data>
        <X509Certificate>MIIC/TCCAeWgAwIBAgIIUd7j/OIahkYwDQYJKoZIhvcNAQELBQAwLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDAeFw0yMzExMDExNjAzMjdaFw0yODExMDExNjAzMjdaMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzZMJFMHQcoR8sE Lf/wLEJtaKvPuuW/Nxeen/SPeOuZv Gy3SKIeJ9IHATQVXVZbv0rLDQABOQt9IsvKWXIK7OChQ6CZd3dgxqoHyZA4Eh5wVAMAeQzWzLOL9XBV0m3wfXIjSE4Zw6S26MM8eJ1UW066gOoBaUKzuQIbCVrMrhJ 7 md8kjhGZTwC o7Rq4ZzGDbggJuk/TUbQ Bu9by6FZJZJJNeZ90iHnrsk4eyC8WvSbUBRC/vBt5HGDKIfCfb2HqDVvBJgkHgjpMwb5wPKC9T2U1YXN5iG2obhn9wDeSFYgyZOrd1XMKyLiJTfT35zQWilZpxMei4fIxFykkVAgMBAAGjITAfMB0GA1UdDgQWBBRNcCE3HDX HOJOu/bKfLYoSX3/0jANBgkqhkiG9w0BAQsFAAOCAQEAExns169MDr1dDNELYNK0JDjPUA6GR50jqfc xa2KOljeXErOdihSvKgDS/vnDN6fjNNZuOMDyr6jjLvRsT0jVWzf/B6v92FrPRa/rv3urGXvW5am3BZyVPipirbiolMTuork95G7y7imftK7117uHcMq3D8f4fxscDiDXgjEEZqjkuzYDGLaVWGJqpv5xE4w K4o2uDwmEIeIX rI1MEVucS2vsvraOrjqjHwc3KrzuVRSsOU7YVHyUhku 7oOrB4tYrVbYYgwd6zXnkdouVPqOX9wTkc9iTmbDP rfkhdadLxU hmMyMuCJKgkZbWKFES7ce23jfTMbpqoHB4pgtQ==</X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>
  <Subject>
    <NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">
      I2jEtI4v3fuD9662-VvgmjE30UFNK2FmdcLRVN05giQ
    </NameID>
    <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" />
  </Subject>
  <Conditions
    NotBefore="2023-12-03T20:21:08.019Z"
    NotOnOrAfter="2023-12-03T21:26:08.019Z">
    <AudienceRestriction>
      <Audience>spn:993d198b-c95f-4aaa-9f10-04a3fec6d1f1</Audience>
    </AudienceRestriction>
  </Conditions>
  <AttributeStatement>
    <Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
      <AttributeValue>ff191596-4ffd-4c77-93e7-6167a5756569</AttributeValue>
    </Attribute>
    <Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
      <AttributeValue>c29b8387-074f-4870-a917-3ef4a25452e7</AttributeValue>
    </Attribute>
    <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
      <AttributeValue>[email protected]</AttributeValue>
    </Attribute>
    <Attribute Name="http://schemas.microsoft.com/identity/claims/displayname">
      <AttributeValue>Test user</AttributeValue>
    </Attribute>
    <Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
      <AttributeValue>https://sts.windows.net/ff191596-4ffd-4c77-93e7-6167a5756569/</AttributeValue>
    </Attribute>
    <Attribute Name="http://schemas.microsoft.com/claims/authnmethodsreferences">
      <AttributeValue>http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password</AttributeValue>
    </Attribute>
  </AttributeStatement>
  <AuthnStatement AuthnInstant="2023-12-03T20:25:56.157Z">
    <AuthnContext>
      <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
    </AuthnContext>
  </AuthnStatement>
</Assertion>

You must validate this security token as a standard SAML assertion, checking that:

  • the assertion’s lifetime is valid. For example, it has not expired, and its age is acceptable to your application.
  • the assertion was issued by the expected Security Token Service that you trust.
  • you are the intended audience of the assertion.
  • the assertion has a valid signature, and you can validate it using the Security Token Service’s public key that you previously loaded from its metadata document. Do not trust the certificate/key in the assertion itself; treat it as a hint.
  • the assertion was signed using a signing algorithm suitable for modern web applications.

Once validated, the Relying Party can start a session for the user using the claims within the SAML assertion, completing single sign-on.

To learn about SAML assertions in more depth, including further validation steps and modern security practices, check out my Pluralsight course: Getting Started with SAML 2.0.

WS-Federation response signing

Ideally, the RequestSecurityTokenResponse element should be signed; otherwise, you cannot prove that the data is valid and has not been tampered with. For example, the Created and Expires elements could have been changed, and the RequestedSecurityToken element changed to contain a different token.

By signing the RequestedSecurityToken element, you can ensure that the RequestedSecurityToken within it has not been swapped for a different one, thanks to the SecurityTokenReference referencing the ID of the SAML assertion in the above example. Binding responses and their tokens in this way can help prevent attackers from injecting stolen WS-Federation sign-in responses into your application.

However, even if you have a signed response, you still have no mechanism to prove that the response or token you received was created in response to your request. It could be a response stolen from a victim that an attacker is injecting into your application, allowing them to sign in as their victim.

If either the response or assertion is signed by the Security Token Service, you get the maximum level of security that WS-Federation can provide. You’ll need to use SAML 2.0 or OpenID Connect to better prevent attackers from injecting tokens into your application.

WS-Federation vs. SAML 2.0

If you have the choice of WS-Federation or SAML 2.0, use SAML. While there is more to get wrong with SAML, it has security features that aren’t present with WS-Federation, such as the ability to verify a link between a request & a response and wider support for a backchannel in the form of the artifact binding.

SAML 2.0 also has wider support than WS-Federation, but just like Microsoft’s modern Azure AD implementations, there’s no reason you can’t support both if required.

WS-Federation vs. OpenID Connect

If you have the choice of WS-Federation or OpenID Connect, use OpenID Connect. OpenID Connect 1.0 builds upon all of the hard lessons learned from WS-Federation and SAML 2.0 and can support any type of application, unlike WS-Federation and SAML, which can only support server-side web applications.

OpenID Connect supports the missing security features of WS-Federation by default, with a protocol requirement of matching requests to responses, no use of XML (most of the big WS-Federation and SAML vulnerabilities were actually XML vulnerabilities), and wide support of backchannel response modes suitable for all types of applications. You even get API security out of the box thanks to OpenID Connect being an extension of OAuth 2.

Is WS-Federation dead?

Yeah, pretty much. You should prefer modern protocols such as OpenID Connect over WS-Federation. OpenID Connect has additional security features that are simply unavailable to WS-Federation and allows you to federate with any kind of application, rather than just web applications that can support XML and a server backend.

I would also recommend a modern SAML 2.0 stack over WS-Federation due to its improved request forgery & replay protection. But ideally, you should use OpenID Connect.

WS-Federation only really saw popularity within the Microsoft ecosystem, so if you’re looking to federate with organizations that use a different stack or expose SSO functionality to the wider world, then you will again need to use something more popular, such as OpenID Connect or SAML 2.0.