title: MVC 5, WIF (System.IdentityModel) & ADFS not actually authenticating, errors on federated signout
body: <p>I'm wading through the creation of a claims-based MVC site in Visual Studio 2013.</p>
  <p>Some things I learned so far:</p>
  <ul>
  <li>System.Identity is in, Microsoft.Identity is out</li>
  <li>Many of the tutorials, including Microsoft's guides for 4.5, are out-dated.  For example, I don't believe any changes to the Project Template-generated .config file are necessary for adding modules/handlers or anything.</li>
  <li>There is no Microsoft built-in/add-in STS in Visual Studio 2013 as there was for 2012</li>
  <li>Thinktecture's EmbeddedSTS addin is oft-recommended and sounds cool, but *://EmbeddedSTS/ doesn't resolve(?? I don't get it).  Also, binary links to their IdentityServer v2- are currently broken(?)</li>
  <li>ADFS feature requires Windows Server 2012, a Domain, and self-signed certs - not too hard if you've done it before, but steep learning curve if you haven't.</li>
  <li>ADFS requires SSL - Visual Studio 2013/IIS Express 8 easily supports SSL sites, just make sure the port number is in the range :44300-44398</li>
  <li>ADFS manager Relying Party interface suggests examples referring to &quot;sts&quot; and &quot;adfs/ls&quot; and stuff which is, I think, misleading.  Really they should just point back to your app (<code>https://localhost:44300</code> for example).  Although mine's not working right yet, so that could be related to my mistake.</li>
  <li>Once you create a new Visual Studio Web Application project, there is no tooling to change the authentication mechanisms.  Just start over with a new project and change the authentication to Organizational Accounts (for on-premises, as in my case).  <em>Your STS, such as your ADFS installation, has to be installed and reachable in order to complete this wizard.</em></li>
  <li>Use the <code>hosts</code> file to override DNS for the VM's IP to the expected domain name if you're hacking together a test ADFS DC in a VM because you don't have rights to join a machine to the domain.</li>
  <li>&quot;Users are required to provide credentials each time the sign in&quot; is helpful when working through sign-in sign-out problems at first.</li>
  <li>I don't think any claims, even identity, are passed if you don't have any Claim Rules.</li>
  </ul>
  <h2>1) What is wrong such that my app still thinks the user is not authenticated?</h2>
  <p>I'm to the point where my <code>https://localhost:44300/Default/Index/</code> action is supposed to display details of <code>User.Identity</code> (I also tried <code>Thread.CurrentPrincipal.Identity</code>) if the user is authenticated.  I have a login Action link, generated with:</p>
  <pre><code>var signIn = new SignInRequestMessage(new Uri(&quot;https://dc.ad.dev.local/adfs/ls/&quot;), &quot;https://localhost:44300&quot;);
  
  return new RedirectResult(signIn.WriteQueryString());
  </code></pre>
  <p>Clicking this link indeed takes me to the ADFS login page.  Logging in brings me back to my application.  Watching the preserved Network activity in Chrome Bug shows that I have a <code>RequestSecurityTokenResponse</code> message being posted back to the app, but the app's <code>User.Identity</code> is still not <em>authenticated</em>.</p>
  <p>I have one Claim Rule configured:  A &quot;Transform an Incoming Claim&quot; from &quot;Windows Account Name&quot; to &quot;Name ID&quot; as a &quot;Transient Identifier&quot;.  I see the <code>&lt;saml:NameIdentifier Format=&quot;urn:oasis:names:tc:SAML:2.0:nameid-format:transient&quot;&gt;DevAD\jdoe&lt;/saml:NameIdentifier&gt;</code> represented in the sniffed <code>POST</code>.  I've tried a bunch of other Claim Rules and still don't get <em>authenticated</em>.</p>
  <p>I don't have any custom code for absorbing the claims.  <strong>I am expect interception of a POST with the token to any app url to be converted to the <code>User.Identity</code> auto-magically by the framework</strong>, perhaps having been initiated by this wizard-generated code in Startup.Auth.cs:</p>
  <pre><code>app.UseActiveDirectoryFederationServicesBearerAuthentication(
      new ActiveDirectoryFederationServicesBearerAuthenticationOptions
      {
          Audience = ConfigurationManager.AppSettings[&quot;ida:Audience&quot;],
          MetadataEndpoint = ConfigurationManager.AppSettings[&quot;ida:AdfsMetadataEndpoint&quot;]
      });
  </code></pre>
  <p>But part of me doubts this expectation.  Is it correct?  Is there a special known route that MVC WIF creates for accepting such login posts that I should be using besides my default route url?</p>
  <h2>2) How can I log out successfully?</h2>
  <p>I also have a logout action:</p>
  <pre><code>WSFederationAuthenticationModule.FederatedSignOut(new Uri(&quot;https://dc.ad.dev.local/adfs/ls/&quot;), new Uri(Url.Action(&quot;Index&quot;, null, null, Request.Url.Scheme)));
  </code></pre>
  <p>But on this <code>https://dc.ad.dev.local/adfs/ls?wa=wsignout1.0&amp;wreply=https%3a%2f%2flocalhost%3a44300%2f</code> page, &quot;An error occurred&quot;.  Event Viewer shows #364: &quot;Encountered error during federation passive request.&quot;</p>
  <pre><code>Protocol Name: 
  wsfed 
  
  Relying Party: 
  
  Exception details: 
  System.ArgumentException: An item with the same key has already been added.
     at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
     at Microsoft.IdentityServer.Web.Protocols.WSFederation.WSFederationProtocolHandler.AddSignoutSessionInformation(WSFederationSignOutContextBase context)
     at Microsoft.IdentityServer.Web.Protocols.WSFederation.WSFederationProtocolHandler.ProcessSignOut(WSFederationSignOutContext context)
     at Microsoft.IdentityServer.Web.PassiveProtocolListener.ProcessProtocolSignoutRequest(ProtocolContext protocolContext, PassiveProtocolHandler protocolHandler)
     at Microsoft.IdentityServer.Web.PassiveProtocolListener.ProcessProtocolRequest(ProtocolContext protocolContext, PassiveProtocolHandler protocolHandler)
     at Microsoft.IdentityServer.Web.PassiveProtocolListener.OnGetContext(WrappedHttpListenerContext context)
  </code></pre>
  <p>My ADFS Service &gt; Certificates are all set to the same cert and I think are correct.</p>
  <p>================</p>
  <p>And by the way, the following <em>is</em> what is supposed to be <em>passively</em> posted to the app, right?  And, again, it is absorbed automatically?</p>
  <pre><code>&lt;t:RequestSecurityTokenResponse xmlns:t=&quot;http://schemas.xmlsoap.org/ws/2005/02/trust&quot;&gt;
      &lt;t:Lifetime&gt;
          &lt;wsu:Created xmlns:wsu=&quot;http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&quot;&gt;2014-07-28T14:29:47.167Z&lt;/wsu:Created&gt;
          &lt;wsu:Expires xmlns:wsu=&quot;http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&quot;&gt;2014-07-28T15:29:47.167Z&lt;/wsu:Expires&gt;
      &lt;/t:Lifetime&gt;
      &lt;wsp:AppliesTo xmlns:wsp=&quot;http://schemas.xmlsoap.org/ws/2004/09/policy&quot;&gt;
          &lt;wsa:EndpointReference xmlns:wsa=&quot;http://www.w3.org/2005/08/addressing&quot;&gt;
              &lt;wsa:Address&gt;https://localhost:44300/&lt;/wsa:Address&gt;
          &lt;/wsa:EndpointReference&gt;
      &lt;/wsp:AppliesTo&gt;
      &lt;t:RequestedSecurityToken&gt;
          &lt;saml:Assertion MajorVersion=&quot;1&quot; MinorVersion=&quot;1&quot; AssertionID=&quot;_e2399a27-acac-4390-aa8a-556f41fec2f2&quot; Issuer=&quot;http://dc.ad.dev.local/adfs/services/trust&quot; IssueInstant=&quot;2014-07-28T14:29:47.167Z&quot; xmlns:saml=&quot;urn:oasis:names:tc:SAML:1.0:assertion&quot;&gt;
              &lt;saml:Conditions NotBefore=&quot;2014-07-28T14:29:47.167Z&quot; NotOnOrAfter=&quot;2014-07-28T15:29:47.167Z&quot;&gt;
                  &lt;saml:AudienceRestrictionCondition&gt;
                      &lt;saml:Audience&gt;https://localhost:44300/&lt;/saml:Audience&gt;
                  &lt;/saml:AudienceRestrictionCondition&gt;
              &lt;/saml:Conditions&gt;
              &lt;saml:AttributeStatement&gt;
                  &lt;saml:Subject&gt;
                      &lt;saml:NameIdentifier Format=&quot;urn:oasis:names:tc:SAML:2.0:nameid-format:transient&quot;&gt;DevAD\jdoe&lt;/saml:NameIdentifier&gt;
                      &lt;saml:SubjectConfirmation&gt;
                          &lt;saml:ConfirmationMethod&gt;urn:oasis:names:tc:SAML:1.0:cm:bearer&lt;/saml:ConfirmationMethod&gt;
                      &lt;/saml:SubjectConfirmation&gt;
                  &lt;/saml:Subject&gt;
                  &lt;saml:Attribute AttributeName=&quot;name&quot; AttributeNamespace=&quot;http://schemas.xmlsoap.org/ws/2005/05/identity/claims&quot;&gt;
                      &lt;saml:AttributeValue&gt;jdoe&lt;/saml:AttributeValue&gt;
                  &lt;/saml:Attribute&gt;
                  &lt;saml:Attribute AttributeName=&quot;givenname&quot; AttributeNamespace=&quot;http://schemas.xmlsoap.org/ws/2005/05/identity/claims&quot;&gt;
                      &lt;saml:AttributeValue&gt;John Doe&lt;/saml:AttributeValue&gt;
                  &lt;/saml:Attribute&gt;
                  &lt;saml:Attribute AttributeName=&quot;upn&quot; AttributeNamespace=&quot;http://schemas.xmlsoap.org/ws/2005/05/identity/claims&quot;&gt;
                      &lt;saml:AttributeValue&gt;jdoe@ad.dev.local&lt;/saml:AttributeValue&gt;
                  &lt;/saml:Attribute&gt;
              &lt;/saml:AttributeStatement&gt;
              &lt;saml:AuthenticationStatement AuthenticationMethod=&quot;urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport&quot; AuthenticationInstant=&quot;2014-07-28T14:29:47.152Z&quot;&gt;
                  &lt;saml:Subject&gt;
                      &lt;saml:NameIdentifier Format=&quot;urn:oasis:names:tc:SAML:2.0:nameid-format:transient&quot;&gt;DevAD\jdoe&lt;/saml:NameIdentifier&gt;
                      &lt;saml:SubjectConfirmation&gt;
                          &lt;saml:ConfirmationMethod&gt;urn:oasis:names:tc:SAML:1.0:cm:bearer&lt;/saml:ConfirmationMethod&gt;
                      &lt;/saml:SubjectConfirmation&gt;
                  &lt;/saml:Subject&gt;
              &lt;/saml:AuthenticationStatement&gt;
              &lt;ds:Signature xmlns:ds=&quot;http://www.w3.org/2000/09/xmldsig#&quot;&gt;
                  &lt;ds:SignedInfo&gt;
                      &lt;ds:CanonicalizationMethod Algorithm=&quot;http://www.w3.org/2001/10/xml-exc-c14n#&quot; /&gt;
                      &lt;ds:SignatureMethod Algorithm=&quot;http://www.w3.org/2001/04/xmldsig-more#rsa-sha256&quot; /&gt;
                      &lt;ds:Reference URI=&quot;#_e2399a27-acac-4390-aa8a-556f41fec2f2&quot;&gt;
                          &lt;ds:Transforms&gt;
                              &lt;ds:Transform Algorithm=&quot;http://www.w3.org/2000/09/xmldsig#enveloped-signature&quot; /&gt;
                              &lt;ds:Transform Algorithm=&quot;http://www.w3.org/2001/10/xml-exc-c14n#&quot; /&gt;
                          &lt;/ds:Transforms&gt;
                          &lt;ds:DigestMethod Algorithm=&quot;http://www.w3.org/2001/04/xmlenc#sha256&quot; /&gt;
                          &lt;ds:DigestValue&gt;+ZDduF0CKxXq7P+diyAXN51mo549pvwo3BNCekWSEpk=&lt;/ds:DigestValue&gt;
                      &lt;/ds:Reference&gt;
                  &lt;/ds:SignedInfo&gt;
                  &lt;ds:SignatureValue&gt;VMjCbSZXw3YROHYQ1eCYH5D9UQl1tzqZ9Nw99FUK78A8TSLs1ns3G8PE1d1Z1db2KKpbnzExXSXG2elP3Z69OejSWjsywIFTPeGcbGk4BvrV4ZcHGCbYKN0Wg5pySMEqm4LV1E5k+32kuALveLi5fkQROyXudquvVRgYrgu7XBsfr96Uvqo1yWmAzhhpEorfe4Z0p4RurKRpS7IsrI9SkssGOdQV/89NQelIZSZzOEMfay/AxewBbQ8C46g/4NgygaaPsG8X52EFVftzFY0BM8k+aMMUiKrJ0Xo7tJCMxJLcQ3aJdLBRNybHaklFgtln0ZCSlYylglUjUZ5d66jGcg==&lt;/ds:SignatureValue&gt;
                  &lt;KeyInfo xmlns=&quot;http://www.w3.org/2000/09/xmldsig#&quot;&gt;
                      &lt;X509Data&gt;
                          &lt;X509Certificate&gt;MIIC7jCCAdagAwIBAgIQLB+dBr0GI75OvLElC1HZHTANBgkqhkiG9w0BAQsFADAzMTEwLwYDVQQDEyhBREZTIFNpZ25pbmcgLSBkYy5hZC5lbnRlcnByaXNlZGV2LmxvY2FsMB4XDTE0MDcyNDIxMTMxM1oXDTE1MDcyNDIxMTMxM1owMzExMC8GA1UEAxMoQURGUyBTaWduaW5nIC0gZGMuYWQuZW50ZXJwcmlzZWRldi5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALvkkbfrr5YZWNkfv7LFQlVj3qTcfduRltKfAGiK/NOXNp498uMY+zhUBtiPU1woJhsoqfahgQpy3YJhIPsxbVGSXjAGcFVcUq03V2xVJB6+tW1Ny+/lqiXrdvYAHcZvqpeG/tnh5/hGi/mapd2oMxWIWkyRdztJrN+BCzUi4mm80bYrYX8liuDAcJEk5EYh73gaOwzIyUAZvOXwX1UWh9FA8j2mIMyv3b4SgjFQMPT+Fyw4L1cX+3u/PhGlVRSUEAu+igfMxM1JTco+3HMfQuBZLGd8YXhig+6WbIGlcGUhHEdNSr9ymljJBaps1JfGZk7Rj/7hYeHCXbl3mKK7yFUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAU5gYs7BZZBrrm+eDZM5pTaQfnwyeHYWHe9D2UDweWTNjj9KVC2sucUI2K9MXzA3kZOP7UIvnLmHvxG7cnPen095NBIyYYDjzvlImGwq297m6cz0m2ZxkBGMKq9bVSPoVOgDrX0c+e2wFjRgVojd1bWm9fbMvIUWn8KyMQMquXmyJxX5sPxpMfm95yheyh6q67VzgWF9TcUp6jNdmMcRowHWnQ9UVYf1UEMcPUlaljARVQYNQjyHjrcFaRkxF57EkjO3e263KIe0knVNoz8W57prXJLOHOqSe2f4kSKUdU+Xt8XQbJ77xHPdSOoW8NwKZVL7/9TrfVJ6pi1Ob/+LrAA==&lt;/X509Certificate&gt;
                      &lt;/X509Data&gt;
                  &lt;/KeyInfo&gt;
              &lt;/ds:Signature&gt;
          &lt;/saml:Assertion&gt;
      &lt;/t:RequestedSecurityToken&gt;
      &lt;t:TokenType&gt;urn:oasis:names:tc:SAML:1.0:assertion&lt;/t:TokenType&gt;
      &lt;t:RequestType&gt;http://schemas.xmlsoap.org/ws/2005/02/trust/Issue&lt;/t:RequestType&gt;
      &lt;t:KeyType&gt;http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey&lt;/t:KeyType&gt;
  &lt;/t:RequestSecurityTokenResponse&gt;
  </code></pre>
  <p>===============</p>
  <p>Below are the Claims defined.  As suggested by @nzpcmad, the second one now &quot;Send LDAP Attributes as Claims&quot; from &quot;Active Directory&quot; to send &quot;SAM-Account-Name&quot; as &quot;Name&quot;, &quot;Display Name&quot; as &quot;Given Name&quot;, and &quot;User-Principal-Name&quot; as &quot;UPN&quot;.  And though the application receives the claims in the passive post, <code>User.Identity.IsAuthenticated</code> is still false and the other <code>User.Identity</code> data are blank too.</p>
  <p><img src="https://i.stack.imgur.com/HuZg8.png" alt="enter image description here" /></p>