title: Authenticating web API by SAML token passed to it
body: <p>I have a Web API on premise (exposed on https) which is called by an external application. This application passes a SAML token (by signing to ADFS 3.0). I need to authenticate the user in Web API using this SAML token and then return the values.</p>
  
  <p>I am aware that SAML is not the best option but the calling application can only send me the SAML token. So I have limited option here.</p>
  
  <p>I was able to add a relaying party in ADFS for my Web API (With WSFed endpoint as my local url) and when I ran the Web API locally from IIS (In browser) then I am able to log in (on ADFS page) and authenticate and get values (With Claims)</p>
  
  <p>So what I did is try to create a Console application that can get a SAML token and then try and pass the SAML token to call the Web API. </p>
  
  <p>Below is the code I am using :</p>
  
  <pre><code>   static void Main(string[] args)
  
          {
  
              const string relyingPartyId = "https://localhost/api/"
              const string adfsEndpoint = "https://adfsserver/adfs/services/trust/13/usernamemixed";
  
              const string certSubject = "CN=&lt;domain&gt;";
  
  
  
              //Setup the connection to ADFS
  
              var factory = new Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), new EndpointAddress(adfsEndpoint))
  
              {
  
                  TrustVersion = TrustVersion.WSTrust13
  
              };
  
  
  
              factory.Credentials.UserName.UserName = "username";
  
              factory.Credentials.UserName.Password = "password";
  
              factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
  
  
  
              //Setup the request object 
  
              var rst = new Microsoft.IdentityModel.Protocols.WSTrust.RequestSecurityToken
  
              {
  
                  RequestType = RequestTypes.Issue,
  
                  KeyType = KeyTypes.Bearer,
  
                  AppliesTo = new System.ServiceModel.EndpointAddress(relyingPartyId)
  
              };
  
  
  
              //Open a connection to ADFS and get a token for the logged in user
  
              var channel = factory.CreateChannel();
  
              var genericToken = channel.Issue(rst) as GenericXmlSecurityToken;
  
  
  
              if (genericToken != null)
  
              {
  
  
                  var samlAssertion = genericToken.TokenXml.OuterXml;
  
  
  
  
                  Check(samlAssertion);
  
  
  
              }
  
  
  
          }
  
  static async void Check(string samlAssertion)
  
          {
  
              try
  
              {
  
                  HttpClient client = new HttpClient();
  
                  HttpRequestMessage request =
  
                      new HttpRequestMessage(HttpMethod.Get, "https://localhost/api/Values");
  
                  request.Headers.Add("Authorization", samlAssertion);
  
                  HttpResponseMessage response = await client.SendAsync(request);
  
  
  
                  string responseString = await response.Content.ReadAsStringAsync();
  
              }
  
              catch(Exception de)
  
              {
  
                  throw de;
  
              }
  
          }
  </code></pre>
  
  <p>This fails when calling "client.SendAsync(...."</p>
  
  <p>I have two question(s):</p>
  
  <ol>
  <li>How do I make this work ? </li>
  <li>Currently we are using a Local ADFS so I get the XML SAML token (readable), but when in production I will get an encrypted SAML token. What changes do I have to make in Web API in case of encrypted SAML token.</li>
  </ol>
  
  <p>I need some help and directions here. Any sample code or blogs would definitely help.</p>
  
  <ul>
  <li>Girija</li>
  </ul>