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:
- 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).
- 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).
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.
- 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.
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.WsFederationis not a viable replacement forMicrosoft.IdentityModel.Protocols.WsTrustinSystem.ServiceModel.FederationSummary
The .NET WCF client repo (dotnet/wcf) ships
System.ServiceModel.Federation, which depends onMicrosoft.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-profileRequestSecurityToken(RST) andRequestSecurityTokenResponse(RSTR) SOAP messages exchanged with a Secure Token Service (STS).The suggested replacement,
Microsoft.IdentityModel.Protocols.WsFederationdoes not provide any of the functionality WCF actually consumes. It is a fundamentally different protocol surface:Microsoft.IdentityModel.Protocols.WsTrust(deprecated)Microsoft.IdentityModel.Protocols.WsFederation(proposed replacement)XmlDictionaryReader/XmlDictionaryWriterreading/writing SOAP body envelopesapplication/x-www-form-urlencodedquery strings / form parameters; XML metadata documentsMicrosoft.IdentityModel.Xml.WsTrustConstants[_1_3 / _1_4 / _2005]WsTrustSerializer.WriteRequest(XmlDictionaryWriter, …)andReadResponse(XmlDictionaryReader)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-TrustRequestSecurityTokenSOAP exchange WCF needs.The WsFederation package's
WsFederationMessagederives fromAuthenticationProtocolMessageand is built aroundFromQueryString/FromUri/BuildRedirectUrl/BuildFormPostfor 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 (
devbranch) confirms that no class namedWsTrustRequest,WsTrustResponse, orWsTrustSerializerexists outside thebrentsch/wstrustfeature branch. That feature branch is the source of the deprecated package; nothing equivalent has been merged forward intodev.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 undersrc/System.ServiceModel.Federation/src/.1. Object model — request side
Used in
WSTrustChannelSecurityTokenProvider.CreateWsTrustRequest()andWSTrustChannel.Microsoft.IdentityModel.Protocols.WsFederation?Microsoft.IdentityModel.Protocols.WsTrust.WsTrustRequest(ctor takes theIssueaction)WsTrustRequest.WsTrustVersion,RequestType,KeyType,KeySizeInBits,TokenType,Context,ComputedKeyAlgorithm,Entropy,Claims,AppliesTo,AdditionalXmlElementsMicrosoft.IdentityModel.Protocols.WsTrust.WsTrustVersion(enum:TrustFeb2005,Trust13,Trust14)Microsoft.IdentityModel.Protocols.WsTrust.WsTrustActions(instance per version with.Issue,.IssueRequest,.Cancel,.CancelRequest,.Renew,.RenewRequest,.Validate,.ValidateRequest)WsTrustConstants_1_3.Actions.Issueetc. 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)WsSerializationContext.TrustKeyTypes.Symmetric / Bearer / PublicKey / PSHA1Microsoft.IdentityModel.Protocols.WsTrust.Entropy(ctor takesBinarySecret;BinarySecret,ProtectedKeyprops)Microsoft.IdentityModel.Protocols.WsTrust.BinarySecret(Databyte array)Microsoft.IdentityModel.Protocols.WsPolicy.AppliesTo(ctor takesEndpointReference)Microsoft.IdentityModel.Protocols.WsAddressing.EndpointReference(ctor takes string)AppliesToMicrosoft.IdentityModel.Protocols.WsFed.Claims(ctor takes dialect +IList<ClaimType>;Dialect,ClaimTypes)Microsoft.IdentityModel.Protocols.WsFed.ClaimType(Uri,Value,IsOptional)Microsoft.IdentityModel.Protocols.WsTrust.Psha1KeyGenerator.FillRandomBytes(byte[])andComputeCombinedKey(byte[], byte[], int)2. Object model — response side
Used in
WSTrustUtilities.CreateGenericXmlSecurityToken/GetProofTokenand inWSTrustChannelSecurityTokenProvider.IsWsTrustResponseExpired.Microsoft.IdentityModel.Protocols.WsTrust.WsTrustResponse(RequestSecurityTokenResponseCollection)Microsoft.IdentityModel.Protocols.WsTrust.RequestSecurityTokenResponse(KeyType,KeySizeInBits,RequestedSecurityToken,RequestedProofToken,Entropy,AttachedReference,UnattachedReference,Lifetime)Microsoft.IdentityModel.Protocols.WsTrust.RequestedSecurityToken.TokenElement(XmlElement)GenericXmlSecurityTokenMicrosoft.IdentityModel.Protocols.WsTrust.RequestedProofToken(BinarySecret,ComputedKeyAlgorithm,EncryptedKey)Microsoft.IdentityModel.Protocols.WsTrust.Lifetime(Created,Expires)Microsoft.IdentityModel.Protocols.WsSecurity.SecurityTokenReference<o:SecurityTokenReference>Microsoft.IdentityModel.Protocols.WsSecurity.WsSecuritySerializer.CreateXmlElement(SecurityTokenReference)XmlElementto feedGenericXmlSecurityKeyIdentifierClause3. Serializer — the central capability
Used in
WSTrustRequestBodyWriter.OnWriteBodyContents,WSTrustChannel.IssueAsync, andWSTrustChannelSecurityTokenProvider.GetTokenCore/GetTokenAsyncCore.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 withContext,RequestType,TokenType,KeyType,KeySize,AppliesTo,Claims,Entropy,BinarySecret,ComputedKeyAlgorithm, plus arbitraryAdditionalXmlElementsextension points<wst:RequestSecurityTokenResponseCollection>/<wst:RequestSecurityTokenResponse>reading:RequestedSecurityToken(extracts the embedded SAML/SAML2XmlElement),RequestedProofToken(binary or computed-key), serverEntropy,Lifetime(xsd:dateTimeCreated/Expires),RequestedAttachedReferenceandRequestedUnattachedReferencecontainingSecurityTokenReference200512), WS-Trust 1.4 (OASIS200802), and WS-Trust Feb 2005 (xmlsoap.org/2005/02) namespaces and element/attribute differencesReplacement availability:
Microsoft.IdentityModel.Protocols.WsFederationexposes no serializer at all for these messages.WsFederationMetadataSerializerreads/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.txtondev:WsFederationConfiguration,WsFederationConfigurationRetriever,WsFederationConfigurationValidator,SecurityTokenServiceTypeRoleDescriptor— federation metadata discovery and validationWsFederationMessage(extendsAuthenticationProtocolMessage) — passive/browser profile message with query-string parameters (wa,wtrealm,wctx,wresult, etc.) andBuildRedirectUrl/BuildFormPostWsFederationMetadataSerializer— read/write the WS-Federation metadata documentWsFederationConstants, plusMicrosoft.IdentityModel.Xml.WsTrustConstants,WsTrustConstants_1_3,WsTrustConstants_1_4,WsTrustConstants_2005,WsAddressingConstants,WsPolicyConstants,WsUtilityConstantsWsFederationExceptionNone of these provide an object model or serializer for
<wst:RequestSecurityToken>/<wst:RequestSecurityTokenResponse>.Conclusion / requested action
To unblock migration of
System.ServiceModel.Federationoff the deprecatedMicrosoft.IdentityModel.Protocols.WsTrust, an actively-maintained replacement must provide, at minimum:WsTrustRequest,WsTrustResponse,RequestSecurityTokenResponseEntropy,BinarySecret,RequestedProofToken,RequestedSecurityToken,Lifetime,AppliesTo,EndpointReference,Claims,ClaimType,SecurityTokenReferenceWsTrustVersionenum and aWsSerializationContext(or equivalent) that exposes per-versionTrustKeyTypes(Symmetric/Bearer/PublicKey/PSHA1) andTrustActions(Issue/Cancel/Renew/Validate plus their…Requestaction URIs).WsTrustSerializer.WriteRequest(XmlDictionaryWriter, WsTrustVersion, WsTrustRequest)andWsTrustSerializer.ReadResponse(XmlDictionaryReader), supporting WS-Trust 1.3, 1.4, and Feb 2005, and supportingXmlDictionaryReader/XmlDictionaryWriter(so it can be plugged directly into a WCFMessagebody viaBodyWriter.OnWriteBodyContentsandMessage.GetReaderAtBodyContents).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.<wsse:SecurityTokenReference>element materialization (today:WsSecuritySerializer.CreateXmlElement(SecurityTokenReference)), since WCF wraps the result inGenericXmlSecurityKeyIdentifierClause.Microsoft.IdentityModel.Protocols.WsFederationcovers a different protocol (passive/browser SSO + federation metadata) and supplies none of the above. As shipped ondev, it is not a functional substitute forMicrosoft.IdentityModel.Protocols.WsTrustforSystem.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.