private (User user, string provider, string providerUserId, IEnumerable <Claim> claims) FindUserFromExternalProvider(AuthenticateResult result) { var externalUser = result.Principal; // try to determine the unique id of the external user (issued by the provider) // the most common claim type for that are the sub claim and the NameIdentifier // depending on the external provider, some other claim type might be used var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ?? externalUser.FindFirst(ClaimTypes.NameIdentifier) ?? throw new Exception("Unknown userid"); // remove the user id claim so we don't include it as an extra claim if/when we provision the user var claims = externalUser.Claims.ToList(); claims.Remove(userIdClaim); var provider = result.Properties.Items["scheme"]; var providerUserId = userIdClaim.Value; // find external user var user = _users.FindByExternalProvider(provider, providerUserId); if (user == null) { var email = claims.SingleOrDefault(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")?.Value; if (email != null) { user = _users.FindByEmail(email); if (user != null) { _users.AddExternalProviderId(user, provider, providerUserId); } } } return(user, provider, providerUserId, claims); }