I see the following concerns here:

- Check for banned IP. Checks whether user's IP is in a banned IP range. You will execute this no matter what.
- Check if trials exceeded. Checks whether user have exceeded their login attempts. You will execute this no matter what.
- Authenticate user. Attempt to authenticate user.

I would do the following:

    CheckBannedIP(login.IP);
    CheckLoginTrial(login);
    
    Authenticate(login.Username, login.Password);


    public void CheckBannedIP(string ip)
    {
        // If banned then re-direct, else do nothing.
    }

    public void CheckLoginTrial(LoginAttempt login)
    {
        // If exceeded trials, then inform user, else do nothing
    }

    public void Authenticate(string username, string password)
    {
         // Attempt to authenticate. On success redirect, else catch any errors and inform the user. 
    }

Currently your example has too many responsibilities. All I did, was encapsulate those responsibilities within methods. Code looks cleaner and you don't have condition statements all over the place.

Factory encapsulates construction of objects. You don't need to encapsulate construction of anything in your example, all you need to do is to separate your concerns.