title: How to renew a SAML assertion with ADFS?
body: <p>I am able to succesfully request a SAML SecurityToken from ADFS with a user name and password using the following code:</p>
  
  <pre><code>private GenericXmlSecurityToken IssueToken(string userName, string password)
  {
      var relyingPartyIdentifier = new EndpointReference("https://mywebsite.net");
      var stsAddress = "https://myadfs.com/adfs/services/trust/13/usernamemixed";
      var wsBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
  
      wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
      wsBinding.Security.Message.EstablishSecurityContext = false;
      wsBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
  
      var trustChannelFactory = new WSTrustChannelFactory(wsBinding, stsAddress);
      trustChannelFactory.Credentials.SupportInteractive = false;
      trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
      trustChannelFactory.Credentials.UserName.Password = password;
      trustChannelFactory.Credentials.UserName.UserName = userName;
  
      var tokenRequest = new RequestSecurityToken()
      {
          RequestType = RequestTypes.Issue,
          AppliesTo = relyingPartyIdentifier,
          KeyType = KeyTypes.Symmetric,
          TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"
      };
  
      tokenRequest.Claims.Add(new RequestClaim(ClaimTypes.Name));
      tokenRequest.Claims.Add(new RequestClaim(ClaimTypes.Email));
  
      var channel = trustChannelFactory.CreateChannel();
      var token = (GenericXmlSecurityToken)channel.Issue(tokenRequest);
  
      return token;
  }
  </code></pre>
  
  <p>However, that token will expire in an hour. So my question is, how can I issue a new token based on the initial token, such that I don't need to remember the username and password?</p>
  
  <p>I tried the following code:</p>
  
  <pre><code>public GenericXmlSecurityToken RenewToken(SecurityToken token)
  {
      var relyingPartyIdentifier = new EndpointReference("https://mywebsite.net");
      var stsAddress = "https://myadfs.com/adfs/services/trust/13/usernamemixed";
      var wsBinding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
  
      wsBinding.Security.Message.EstablishSecurityContext = false;
      wsBinding.Security.Message.IssuerAddress = new EndpointAddress(new Uri(stsAddress));
      wsBinding.Security.Message.IssuerBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
      wsBinding.Security.Message.IssuerMetadataAddress = new EndpointAddress("https://myadfs.com/adfs/services/trust/mex");
  
      var trustChannelFactory = new WSTrustChannelFactory(wsBinding, stsAddress);
      trustChannelFactory.Credentials.SupportInteractive = false;
      trustChannelFactory.Credentials.UserName.UserName = Settings.UserName;
      trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
  
      var tokenRequest = new RequestSecurityToken()
      {
          RequestType = RequestTypes.Renew,
          RenewTarget = new SecurityTokenElement(token),
          AppliesTo = relyingPartyIdentifier,
          KeyType = KeyTypes.Symmetric,
          TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1",
      };
  
      tokenRequest.Claims.Add(new RequestClaim(ClaimTypes.Name));
      tokenRequest.Claims.Add(new RequestClaim(ClaimTypes.Email));
  
      var channel = trustChannelFactory.CreateChannel();
  
      // This call fails with: 
      // SecurityNegotiationException: Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint. '
      // Inner Exception: FaultException: An error occurred when verifying security for the message.
      var newToken = (GenericXmlSecurityToken)channel.Issue(tokenRequest);
  
      return newToken;
  }
  </code></pre>
  
  <p>But the call to <code>channel.Issue</code> fails with the following exception:</p>
  
  <p><strong>SecurityNegotiationException:</strong> Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint. '</p>
  
  <p><strong>Inner Exception:</strong> FaultException: An error occurred when verifying security for the message.</p>
  
  <p>I am completely clueless as how to get a new token using the initial token.</p>