title: How to get from ADFS a non-empty Recipient attribute in SAML Assertion
body: <p>I'm trying to get a SAML Assertion from ADFS using WIF 4.5, and WS-Trust, so that I can send that Assertion to a Service Provider and obtain an OAuth ticket. </p>
  
  <p>In fact, I've been able to get the SAML Assertion, but it's not a valid one, because the Recipient attribute from SubjectConfirmationData is not received. And it is a mandatory datum.</p>
  
  <p>I'm doing my test in a Console Application (so it's executing with my credentials, as I have checked using Fiddler, it performs a Kerberos negotiation before receiving the Assertion). I'm obtaining the token doing so (based on <a href="https://stackoverflow.com/questions/14248040/requestsecuritytoken-using-windows-credentials-and-net-4-5-wif">RequestSecurityToken using windows credentials and .net 4.5 WIF</a>):</p>
  
  <pre><code>public static string GetStsToken()
  {
      try
      {
          EndpointReference appliesToEp = new EndpointReference(ENDPOINT_REFERENCE_URI);
  
          EndpointAddress stsEp = new EndpointAddress(
                  new Uri("https://&lt;ADFS-SERVER&gt;/adfs/services/trust/2005/windowstransport"),
                  EndpointIdentity.CreateSpnIdentity(ADFS_SPN));
  
          WS2007HttpBinding msgBinding = new WS2007HttpBinding(SecurityMode.Transport, false);
          msgBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
          msgBinding.Security.Message.EstablishSecurityContext = false;
          msgBinding.Security.Message.NegotiateServiceCredential = false;
          msgBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
  
          using (WSTrustChannelFactory factory = new WSTrustChannelFactory(msgBinding, stsEp))
          {
              factory.Credentials.SupportInteractive = false;
              factory.TrustVersion = TrustVersion.WSTrustFeb2005;
  
              RequestSecurityToken myRst = 
                  new RequestSecurityToken(RequestTypes.Issue, KeyTypes.Bearer)
                  {
                      AppliesTo = appliesToEp,
                      TokenType = "urn:oasis:names:tc:SAML:2.0:assertion"
                  };
              IWSTrustChannelContract channel = factory.CreateChannel();
              GenericXmlSecurityToken stsToken = channel.Issue(myRst) as GenericXmlSecurityToken;
  
              if (stsToken != null)
              {
                  return stsToken.TokenXml.OuterXml;
              }
              else
              {
                  // SOME WARNING IS ISSUED
              }
          }
      }
      catch (Exception ex)
      {
          // THE EXCEPTION IS REGISTERED
      }
  
      return null;
  }
  </code></pre>
  
  <p>With this code, the request sent is the following:</p>
  
  <pre><code>&lt;s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"&gt;
    &lt;s:Header&gt;
      &lt;a:Action s:mustUnderstand="1"&gt;http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue&lt;/a:Action&gt;
      &lt;a:MessageID&gt;urn:uuid:8c221169-52b2-42bf-87f8-7089b6feb0a9&lt;/a:MessageID&gt;
      &lt;a:ReplyTo&gt;
        &lt;a:Address&gt;http://www.w3.org/2005/08/addressing/anonymous&lt;/a:Address&gt;
      &lt;/a:ReplyTo&gt;
      &lt;a:To s:mustUnderstand="1"&gt;https://ADFS-SERVER/adfs/services/trust/2005/windowstransport&lt;/a:To&gt;
    &lt;/s:Header&gt;
    &lt;s:Body&gt;
      &lt;t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"&gt;
        &lt;wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"&gt;
          &lt;wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing"&gt;
            &lt;wsa:Address&gt;ENDPOINT_REFERENCE&lt;/wsa:Address&gt;
          &lt;/wsa:EndpointReference&gt;
        &lt;/wsp:AppliesTo&gt;
        &lt;t:KeySize&gt;0&lt;/t:KeySize&gt;
        &lt;t:KeyType&gt;http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey&lt;/t:KeyType&gt;
        &lt;t:RequestType&gt;http://schemas.xmlsoap.org/ws/2005/02/trust/Issue&lt;/t:RequestType&gt;
        &lt;t:TokenType&gt;urn:oasis:names:tc:SAML:2.0:assertion&lt;/t:TokenType&gt;
      &lt;/t:RequestSecurityToken&gt;
    &lt;/s:Body&gt;
  &lt;/s:Envelope&gt;
  </code></pre>
  
  <p>The Assertion I receive seems a valid one, but the Recipient is missing from the SubjectConfirmationData, and so, when I send that Assertion to the Service Provider, the Authentication fails.</p>
  
  <p>If I use the Web IdP Initiated Login, which sends a <code>samlp:AuthnRequest</code> to the server, and decode the obtained SAML Assertion that ADFS emits in that case (again, using Fiddler), the Recipient attribute is received, and the SSO works. I can see the method used to obtain the assertion is different (Web-SSO is used in this case), but in both cases the Relying Party is the same, and so the emitted Assertion should be similar.</p>
  
  <p>Is there any way I can receive the proper Recipient when obtaining the Token using WS-Trust from ADFS?</p>