title: How do I Sign In using OWIN with SAML ticket returned from ADFS using ASP.NET MVC?
body: <p>I have a website that has it's own login screen, where the user types in their username and password. Upon hitting the login button, the user should be authenticated through ADFS, and I should get a SAML token back. This works. At this point though, I am unsure of what I need to do to login the user.The reason I am unsure is because there is a bit of a twist to this website. As I had said, a user signs in through ADFS via our website's login page. However, if a user visits an unauthorized page, instead of redirecting the user to our login page, we need to have the user redirected to our ADFS login page. I started out the whole project this way. A user authenticates through ADFS's login page. This was done simply by setting up my ConfigureAuth method (in StartupAuth.cs) like this:</p>
  
  <pre><code>public void ConfigureAuth(IAppBuilder app)
  {
      app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
  
      app.UseCookieAuthentication(new CookieAuthenticationOptions());
  
      app.UseWsFederationAuthentication(
          new WsFederationAuthenticationOptions
          {
              Wtrealm = realm,
              MetadataAddress = adfsMetadata
          });
  }
  </code></pre>
  
  <p>Simple enough! If I try to go to an <code>[Authorized]</code> page, it brings me to the ADFS login page. After this it was time to work on the other method of logging in (via using the login page to autheticate with ADFS). Keep in mind that either way that you try to authenticate, you are still authenticating with the same ADFS; one you are using ADFS's login page and the other you are using a custom login page. So I create the custom login page with a simple little form for logging in:</p>
  
  <pre><code>&lt;form action="@Url.Action("SignIn", "Account")" method="post"&gt;
      &lt;input type="text" name="username" /&gt;
      &lt;input type="password" name="password" /&gt;
      &lt;input type="submit" value="Login" /&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>This works just fine. Upon hitting the submit button, it attempts the SignIn action. The SignIn action looks like this:</p>
  
  <pre><code>[HttpPost]
  public ActionResult SignIn(string username, string password)
  {
      if (!Request.IsAuthenticated)
      {
          const string _relyingPartyUri = "https://myrelayingparty/";
          const string _serverName = "myservername";
          const string certSubject = "CN=mycertsubject";
          string endpointUri = string.Format("https://{0}/adfs/services/trust/13/usernamemixed", _serverName);
  
          var factory = new WSTrustChannelFactory(new UserNameWSTrustBinding(), endpointUri)
          {
              TrustVersion = TrustVersion.WSTrust13
          };
  
          factory.Credentials.UserName.UserName = @"mydomain\" + username;
          factory.Credentials.UserName.Password = password;
  
          var rst = new RequestSecurityToken
          {
              RequestType = RequestTypes.Issue,
              AppliesTo = new EndpointReference(_relyingPartyUri),
              KeyType = KeyTypes.Bearer
          };
  
          var channel = factory.CreateChannel();
  
          var genericToken = channel.Issue(rst) as GenericXmlSecurityToken;
  
          if (genericToken != null)
          {
              //Setup the handlers needed to convert the generic token to a SAML Token
              var tokenHandlers = new SecurityTokenHandlerCollection(new SecurityTokenHandler[] { new SamlSecurityTokenHandler() });
              tokenHandlers.Configuration.AudienceRestriction = new AudienceRestriction();
              tokenHandlers.Configuration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(_relyingPartyUri));
  
              var trusted = new TrustedIssuerNameRegistry(certSubject);
              tokenHandlers.Configuration.IssuerNameRegistry = trusted;
  
              //convert the generic security token to a saml token
              SecurityToken samlToken = tokenHandlers.ReadToken(new XmlTextReader(new StringReader(genericToken.TokenXml.OuterXml)));
  
              //convert the saml token to a claims principal
              var claimsPrincipal = new ClaimsPrincipal(tokenHandlers.ValidateToken(samlToken).First());
  
  
              HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = true, RedirectUri = "Home/Homepage" },
                  claimsPrincipal.Identities.ElementAt(0));
          }
      }
  
      return RedirectToAction("Index", "Home");
  }
  </code></pre>
  
  <p>It can successfully retrieve and create the samlToken, and can even validate it and create the claimsPrincipal. I'm not sure what to do after this point to in order to sign in. I tried using <code>HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = true, RedirectUri = "Home/Homepage" },
                  claimsPrincipal.Identities.ElementAt(0));</code>, but if I check Request.IsAuthenticated after that, it is still false. I have a sneaking suspicion that additional onfiguration in my StartupAuth.cs file is required, but I am not sure, which is why I'm turning to you guys. Thanks for any and all help!</p>