title: ASP .NET Core custom authentication scheme with external login
body: <p>I have a website where users log in on an external website and are redirected back with a token in the querystring. I then validate the token and create the authentication ticket. How would I check on subsequent requests that the user is now logged in? And how would I log a user out?</p>
  <pre><code>    protected override Task&lt;AuthenticateResult&gt; HandleAuthenticateAsync()
      {
          var token = Request.Query[&quot;token&quot;].FirstOrDefault();
  
          if (token != null)
          {
              var validator = new JwtSecurityTokenHandler();
  
              var region = &quot;us-xxx-x&quot;;
              var userPoolId = &quot;us-xxx-xxxxxxx&quot;;
              var appClientId = &quot;xxxxxxxxxxxxxxxxxxxx&quot;;
  
              var cognitoIssuer = $&quot;https://cognito-idp.{region}.amazonaws.com/{userPoolId}&quot;;
              var jwtKeySetUrl = $&quot;{cognitoIssuer}/.well-known/jwks.json&quot;;
  
              var validationParameters = new TokenValidationParameters
              {
                  IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =&gt;
                  {
                      var json = new WebClient().DownloadString(jwtKeySetUrl);
                      var keys = JsonConvert.DeserializeObject&lt;JsonWebKeySet&gt;(json).Keys;
                      return (IEnumerable&lt;SecurityKey&gt;)keys;
                  },
                  ValidIssuer = cognitoIssuer,
                  ValidateIssuerSigningKey = true,
                  ValidateIssuer = true,
                  ValidateLifetime = true,
                  ValidAudience = appClientId
              };
  
              // validate the token 
              var principal = validator.ValidateToken(token, validationParameters, out var validatedToken);
              if (principal.HasClaim(c =&gt; c.Type == ClaimTypes.NameIdentifier))
              {
                  var claims = new[] { new Claim(&quot;token&quot;, token) };
                  var identity = new ClaimsIdentity(claims, nameof(TokenAuthenticationHandler));
                  var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), this.Scheme.Name);
                  return Task.FromResult(AuthenticateResult.Success(ticket));
              }
              else
                  return Task.FromResult(AuthenticateResult.Fail(&quot;Token validation failed&quot;));
          }
          else
              return Task.FromResult(AuthenticateResult.Fail(&quot;No token&quot;));
      }
  </code></pre>