/// <summary>
 /// External: The user has logged in on some other site
 /// Either we are supplied a new identity, in which case we add it to our user store
 /// Or we are supplied an existing identity, in which case we return the claims for this user
 /// </summary>
 /// <param name="identity"></param>
 /// <param name="signInData"></param>
 /// <returns></returns>
 public async Task<AuthenticationResult> AuthenticateExternalAsync(ExternalIdentity identity, SignInData signInData)
 {
     //There must be an identity for this to make sense
     if (identity == null)
     {
         throw new ArgumentNullException("identity");
     }
     //The user manager tries to find a matching user
     var user = await manager.FindAsync(new Microsoft.AspNet.Identity.UserLoginInfo(identity.Provider, identity.ProviderId));
     if (user == null)
     {
         //Create a new account
         return await ProcessNewExternalAccountAsync(identity.Provider, identity.ProviderId, identity.Claims);
     }
     else
     {
         return await ProcessExistingExternalAccountAsync(user.Id, identity.Provider, identity.ProviderId, identity.Claims);
     }
 }
 public async Task<AuthenticationResult> AuthenticateLocalAsync(string username, string password, SignInData signInData)
 {
     try
     {
         var user = await ValidateLocalCredentials(username, password);
         if (user != null)
         {
             return new AuthenticationResult(user.Id, user.UserName, Enumerable.Empty<Claim>());
         }
         else
         {
             return new AuthenticationResult("Account is not able to log in.");
         }
     }
     catch (Exception e)
     {
         Console.WriteLine($"Exception occurred while authenticating user {username}: {e}");
         throw;
     }
 }
        /// <summary>
        /// Authentication from within our control, so we have the username and password.
        /// Find the user and get the claims. It doesn't seem to automatically create new users here.
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="signInData"></param>
        /// <returns></returns>
        public async Task<AuthenticationResult> AuthenticateLocalAsync(string username, string password, SignInData signInData)
        {
            
            if (manager.SupportsUserPassword)
            {
                var user = await manager.FindByNameAsync(username);
                                   
                    if (user != null)
                    {
                        if (manager.SupportsUserLockout &&
                            await manager.IsLockedOutAsync(user.Id))
                        {
                            return null;
                        }

                        if (await manager.CheckPasswordAsync(user, password))
                        {
                            if (manager.SupportsUserLockout)
                            {
                                await manager.ResetAccessFailedCountAsync(user.Id);
                            }
                            var result = await PostAuthenticateLocalAsync(user, signInData);
                            if (result == null)
                            {
                               var claims = await GetClaimsForAuthenticateResult(user);
                               return new AuthenticationResult(user.Id.ToString(), await GetDisplayNameForAccountAsync(user.Id), claims);
                            }

                        return result; 
                        }
                        else if (manager.SupportsUserLockout)
                        {
                            await manager.AccessFailedAsync(user.Id);
                        }
                    }
                
            }

            return null;
        }
 public Task<AuthenticationResult> PreAuthenticateAsync(SignInData signInData)
 {
     return Task.FromResult<AuthenticationResult>(null);
 }
 public Task<AuthenticationResult> PostAuthenticateAsync(SignInData signInData, AuthenticationResult authenticationResult)
 {
     return Task.FromResult<AuthenticationResult>(authenticationResult);
 }
 public Task<AuthenticationResult> AuthenticateExternalAsync(ExternalIdentity identity, SignInData signInData)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Doing nothing
        /// </summary>
        /// <param name="user"></param>
        /// <param name="signInData"></param>
        /// <returns></returns>
        protected virtual Task<AuthenticationResult> PostAuthenticateLocalAsync(User user, SignInData signInData)
        {
            if (user == null)
            {
                return Task.FromResult<AuthenticationResult>(null);
            }

            return Task.FromResult(new AuthenticationResult(
                user.Id, 
                user.UserName, 
                user.Claims.Select(c => new Claim(c.ClaimType, c.ClaimValue))));
        }