Skip to content

Deprecation of Microsoft.IdentityModel.Protocols.WsTrust when System.ServiceModel.Federation needs this #3463

@mconnew

Description

@mconnew

The nuget package Microsoft.IdentityModel.Protocols.WsTrust is needed by System.ServiceModel.Federation. As part of the original work when Microsoft.IdentityModel.Protocols.WsTrust was created, there was an expectation that the implementation would end up in the main development branch. Issue #1623 was opened by someone in the community asking when this would happen. The issue was closed with the recommendation to use Microsoft.IdentityModel.Protocols.WsFederation instead. Here is a summary of the findings using Copilot stating the differences between the two libraries and what's missing:

Findings: Microsoft.IdentityModel.Protocols.WsFederation is not a viable replacement for Microsoft.IdentityModel.Protocols.WsTrust in System.ServiceModel.Federation

Summary

The .NET WCF client repo (dotnet/wcf) ships System.ServiceModel.Federation, which depends on Microsoft.IdentityModel.Protocols.WsTrust (last released v6.8.0, now deprecated). The package was used to build, send, and parse WS-Trust 1.3 / WS-Trust 1.4 / WS-Trust Feb 2005 active-profile RequestSecurityToken (RST) and RequestSecurityTokenResponse (RSTR) SOAP messages exchanged with a Secure Token Service (STS).

The suggested replacement, Microsoft.IdentityModel.Protocols.WsFederation does not provide any of the functionality WCF actually consumes. It is a fundamentally different protocol surface:

Concern Microsoft.IdentityModel.Protocols.WsTrust (deprecated) Microsoft.IdentityModel.Protocols.WsFederation (proposed replacement)
Profile WS-Trust active profile (SOAP RST/RSTR) WS-Federation passive/browser profile (HTTP query string / form POST) + federation metadata parsing
Wire format XmlDictionaryReader / XmlDictionaryWriter reading/writing SOAP body envelopes application/x-www-form-urlencoded query strings / form parameters; XML metadata documents
Object model for RST/RSTR Yes – full hierarchy Missing entirely – only string constants in Microsoft.IdentityModel.Xml.WsTrustConstants[_1_3 / _1_4 / _2005]
Serializer for RST/RSTR WsTrustSerializer.WriteRequest(XmlDictionaryWriter, …) and ReadResponse(XmlDictionaryReader) None

The WsFederation package's only XML-format support is WsFederationMetadataSerializer, which parses WS-Federation metadata documents (entity descriptors, role descriptors, signing keys). That is unrelated to the active WS-Trust RequestSecurityToken SOAP exchange WCF needs.

The WsFederation package's WsFederationMessage derives from AuthenticationProtocolMessage and is built around FromQueryString / FromUri / BuildRedirectUrl / BuildFormPost for the browser-redirect sign-in flow. It cannot construct or parse a SOAP <wst:RequestSecurityToken> body.

Code search of the AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet repository (dev branch) confirms that no class named WsTrustRequest, WsTrustResponse, or WsTrustSerializer exists outside the brentsch/wstrust feature branch. That feature branch is the source of the deprecated package; nothing equivalent has been merged forward into dev.

What WCF actually consumes from Microsoft.IdentityModel.Protocols.WsTrust (v6.8.0)

Below is the complete API surface used by System.ServiceModel.Federation. Each entry must be replaced one-for-one (or by an equivalent capability) for the migration to be feasible. Citations point to WCF source under src/System.ServiceModel.Federation/src/.

1. Object model — request side

Used in WSTrustChannelSecurityTokenProvider.CreateWsTrustRequest() and WSTrustChannel.

Type / member (deprecated namespace) Used as Equivalent in Microsoft.IdentityModel.Protocols.WsFederation?
Microsoft.IdentityModel.Protocols.WsTrust.WsTrustRequest (ctor takes the Issue action) The mutable RST message Missing
WsTrustRequest.WsTrustVersion, RequestType, KeyType, KeySizeInBits, TokenType, Context, ComputedKeyAlgorithm, Entropy, Claims, AppliesTo, AdditionalXmlElements All used to populate the RST body Missing
Microsoft.IdentityModel.Protocols.WsTrust.WsTrustVersion (enum: TrustFeb2005, Trust13, Trust14) Selects the wire version Missing (only namespace string constants exist)
Microsoft.IdentityModel.Protocols.WsTrust.WsTrustActions (instance per version with .Issue, .IssueRequest, .Cancel, .CancelRequest, .Renew, .RenewRequest, .Validate, .ValidateRequest) Computes WS-A action Missing (only WsTrustConstants_1_3.Actions.Issue etc. as raw strings — no Cancel/Renew/Validate constants and no version-keyed lookup object)
Microsoft.IdentityModel.Protocols.WsTrust.WsSerializationContext (new WsSerializationContext(WsTrustVersion); .TrustVersion, .TrustActions, .TrustKeyTypes) Per-version constants container used throughout Missing
WsSerializationContext.TrustKeyTypes.Symmetric / Bearer / PublicKey / PSHA1 Canonical key type URIs per version Missing (raw string constants are not exposed)
Microsoft.IdentityModel.Protocols.WsTrust.Entropy (ctor takes BinarySecret; BinarySecret, ProtectedKey props) Carries client entropy Missing
Microsoft.IdentityModel.Protocols.WsTrust.BinarySecret (Data byte array) Entropy payload Missing
Microsoft.IdentityModel.Protocols.WsPolicy.AppliesTo (ctor takes EndpointReference) Target service URL Missing
Microsoft.IdentityModel.Protocols.WsAddressing.EndpointReference (ctor takes string) WS-A EPR for AppliesTo Missing
Microsoft.IdentityModel.Protocols.WsFed.Claims (ctor takes dialect + IList<ClaimType>; Dialect, ClaimTypes) Requested claims block Missing (no equivalent class even in the suggested replacement)
Microsoft.IdentityModel.Protocols.WsFed.ClaimType (Uri, Value, IsOptional) Single requested claim Missing
Microsoft.IdentityModel.Protocols.WsTrust.Psha1KeyGenerator.FillRandomBytes(byte[]) and ComputeCombinedKey(byte[], byte[], int) Generates client entropy and computes PSHA1 combined key per WS-Trust §4.4.3 Missing

2. Object model — response side

Used in WSTrustUtilities.CreateGenericXmlSecurityToken / GetProofToken and in WSTrustChannelSecurityTokenProvider.IsWsTrustResponseExpired.

Type / member Used as Equivalent in WsFederation pkg?
Microsoft.IdentityModel.Protocols.WsTrust.WsTrustResponse (RequestSecurityTokenResponseCollection) Top-level deserialized RSTR(C) Missing
Microsoft.IdentityModel.Protocols.WsTrust.RequestSecurityTokenResponse (KeyType, KeySizeInBits, RequestedSecurityToken, RequestedProofToken, Entropy, AttachedReference, UnattachedReference, Lifetime) Single RSTR Missing
Microsoft.IdentityModel.Protocols.WsTrust.RequestedSecurityToken.TokenElement (XmlElement) The actual SAML/SAML2 token XML to wrap as GenericXmlSecurityToken Missing
Microsoft.IdentityModel.Protocols.WsTrust.RequestedProofToken (BinarySecret, ComputedKeyAlgorithm, EncryptedKey) Proof key delivery Missing
Microsoft.IdentityModel.Protocols.WsTrust.Lifetime (Created, Expires) Token validity window for caching/expiration Missing
Microsoft.IdentityModel.Protocols.WsSecurity.SecurityTokenReference Attached / unattached <o:SecurityTokenReference> Missing
Microsoft.IdentityModel.Protocols.WsSecurity.WsSecuritySerializer.CreateXmlElement(SecurityTokenReference) Materializes STR as XmlElement to feed GenericXmlSecurityKeyIdentifierClause Missing

3. Serializer — the central capability

Used in WSTrustRequestBodyWriter.OnWriteBodyContents, WSTrustChannel.IssueAsync, and WSTrustChannelSecurityTokenProvider.GetTokenCore / GetTokenAsyncCore.

// Write
new WsTrustSerializer().WriteRequest(XmlDictionaryWriter, WsTrustVersion, WsTrustRequest);

// Read
WsTrustResponse response = new WsTrustSerializer().ReadResponse(XmlDictionaryReader);

This is the single most important missing capability. It performs the entire RST and RSTR(C) XML serialization/deserialization across all three trust versions, including:

  • <wst:RequestSecurityToken> envelope with Context, RequestType, TokenType, KeyType, KeySize, AppliesTo, Claims, Entropy, BinarySecret, ComputedKeyAlgorithm, plus arbitrary AdditionalXmlElements extension points
  • <wst:RequestSecurityTokenResponseCollection> / <wst:RequestSecurityTokenResponse> reading: RequestedSecurityToken (extracts the embedded SAML/SAML2 XmlElement), RequestedProofToken (binary or computed-key), server Entropy, Lifetime (xsd:dateTime Created/Expires), RequestedAttachedReference and RequestedUnattachedReference containing SecurityTokenReference
  • WS-Trust 1.3 (OASIS 200512), WS-Trust 1.4 (OASIS 200802), and WS-Trust Feb 2005 (xmlsoap.org/2005/02) namespaces and element/attribute differences

Replacement availability: Microsoft.IdentityModel.Protocols.WsFederation exposes no serializer at all for these messages. WsFederationMetadataSerializer reads/writes federation metadata XML, not WS-Trust messages. WsFederationMessage (de)serializes browser-redirect query strings, not SOAP bodies.

4. What the WsFederation package does provide (for completeness)

Per PublicAPI.Shipped.txt on dev:

  • WsFederationConfiguration, WsFederationConfigurationRetriever, WsFederationConfigurationValidator, SecurityTokenServiceTypeRoleDescriptor — federation metadata discovery and validation
  • WsFederationMessage (extends AuthenticationProtocolMessage) — passive/browser profile message with query-string parameters (wa, wtrealm, wctx, wresult, etc.) and BuildRedirectUrl / BuildFormPost
  • WsFederationMetadataSerializer — read/write the WS-Federation metadata document
  • Constant tables: WsFederationConstants, plus Microsoft.IdentityModel.Xml.WsTrustConstants, WsTrustConstants_1_3, WsTrustConstants_1_4, WsTrustConstants_2005, WsAddressingConstants, WsPolicyConstants, WsUtilityConstants
  • WsFederationException

None of these provide an object model or serializer for <wst:RequestSecurityToken> / <wst:RequestSecurityTokenResponse>.

Conclusion / requested action

To unblock migration of System.ServiceModel.Federation off the deprecated Microsoft.IdentityModel.Protocols.WsTrust, an actively-maintained replacement must provide, at minimum:

  1. A WS-Trust active-profile object model equivalent to:
    • WsTrustRequest, WsTrustResponse, RequestSecurityTokenResponse
    • Entropy, BinarySecret, RequestedProofToken, RequestedSecurityToken, Lifetime, AppliesTo, EndpointReference, Claims, ClaimType, SecurityTokenReference
    • WsTrustVersion enum and a WsSerializationContext (or equivalent) that exposes per-version TrustKeyTypes (Symmetric/Bearer/PublicKey/PSHA1) and TrustActions (Issue/Cancel/Renew/Validate plus their …Request action URIs).
  2. A serializer equivalent to WsTrustSerializer.WriteRequest(XmlDictionaryWriter, WsTrustVersion, WsTrustRequest) and WsTrustSerializer.ReadResponse(XmlDictionaryReader), supporting WS-Trust 1.3, 1.4, and Feb 2005, and supporting XmlDictionaryReader/XmlDictionaryWriter (so it can be plugged directly into a WCF Message body via BodyWriter.OnWriteBodyContents and Message.GetReaderAtBodyContents).
  3. Psha1KeyGenerator (or an equivalent helper) implementing PSHA1 combined-key derivation per WS-Trust 1.3 §4.4.3 and a cryptographically-strong random byte filler.
  4. Continued support for <wsse:SecurityTokenReference> element materialization (today: WsSecuritySerializer.CreateXmlElement(SecurityTokenReference)), since WCF wraps the result in GenericXmlSecurityKeyIdentifierClause.

Microsoft.IdentityModel.Protocols.WsFederation covers a different protocol (passive/browser SSO + federation metadata) and supplies none of the above. As shipped on dev, it is not a functional substitute for Microsoft.IdentityModel.Protocols.WsTrust for System.ServiceModel.Federation's use case.

Alternatively, migrate the Microsoft.IdentityModel.Protocols.WsTrust implementation to the dev branch and release it along with the other packages with a current version number.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions