37

I have been given the assignment of modifying an ASP.NET MVC application in such a way that navigating to myurl?username=xxxxxx automatically logs in user xxxxxx, without asking for a password.

I already made it very clear that this is a terrible idea for many security-related reasons and scenarios, but the people in charge are determined. The site would not be publicly available.

So: is there any way of signing in without a password by, for example, extending the Microsoft.AspNet.Identity.UserManager and modifying the AccountController?

Some code:

var user = await _userManager.FindAsync(model.UserName, model.Password);
if (user != null && IsAllowedToLoginIntoTheCurrentSite(user))
{
    user = _genericRepository.LoadById<User>(user.Id);
    if (user.Active)
    {
        await SignInAsync(user, model.RememberMe);

_userManager holds an instance of a Microsoft.AspNet.Identity.UserManager.

and SignInAsync():

private async Task SignInAsync(User user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    var identity = await _userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
    if (user.UserGroupId.IsSet())
        user.UserGroup = await _userManager.Load<UserGroup>(user.UserGroupId);

    //adding claims here ... //

    AuthenticationManager.SignIn(
        new AuthenticationProperties { IsPersistent = isPersistent }, 
        new CustomClaimsIdentity(identity));
}

AuthenticationManager would be OwinSecurity.

5
  • Show us your login code :) Commented Jan 23, 2015 at 13:29
  • 1
    ...and of course no company ever has problems with insider threats cough Snowden cough. As to your question, yes it's easy. Making things less secure always is. I'd be tempted to set everyone's password to an empty string and use it implicitly (quick 'n dirty but it'll work and also make the point that your security is worthless at the same time). If you want to do it "properly", you can subclass the auth providers Commented Jan 23, 2015 at 13:29
  • @AndyRefuerzo: I've added relevant code. Commented Jan 23, 2015 at 13:56
  • @Basic: The user accounts and passwords would have to remain as they are. The normal user/pass login page should remain in place. The URL I spoke of would simply be an extra backdoor. Commented Jan 23, 2015 at 13:56
  • @Bjorn If you leave your user accounts with passwords that can be bypassed using a "magic" url, you're providing a false sense of security. This is the worst possible kind of system design. If you can't convince your boss this is a bad idea, consider talking to someone up the chain more risk-averse (and competent). Commented Jan 26, 2015 at 2:14

2 Answers 2

111

You just need to use the usermanager to find the user by name. If you have a record then just sign them in.

    public ActionResult StupidCompanyLogin()
    {

        return View();
    }

    [HttpPost]
    //[ValidateAntiForgeryToken] - Whats the point? F**k security 
    public async Task<ActionResult> StupidCompanyLogin(string name)
    {

        var user = await UserManager.FindByNameAsync(name);

        if (user != null)
        {

            await SignInManager.SignInAsync(user, true, true);
        }

        return View();
    }
Sign up to request clarification or add additional context in comments.

8 Comments

No problem - Just make sure you cover your back at work!
This is not as "stupid" as it may look. For Mixed-mode authentication you need a second Web site that would login as Windows user and pass somehow its credentials to the Web site with Forms Authentication. Since with Windows login we probably know nothing more than a user name, we can pass this user name and forcibly login a user with username only. Some encryption added and checking where the call came from, or an attempt to use the cookie set by the second Windows Auth application might help increasing the security. So not that "stupid".
In my case, it was a matter of implementing a "login as" feature for an admin to access a department's portal as a specific user. By implementing a quick custom "login as" password check, then logging in as the user without requiring their explicit password, I was able to do this very easily without having to dig into custom membership providers (granted, a custom membership provider would have been a more robust solution in the long run)
Although this code is upsetting, it is very useful for impersonating a user in local debug (can lock down to DEBUG and localhost only), with full cookies and all, to diagnose a user specific issue, especially Controller-level Roles permissions issues.
Is it still a "stupid login" if I want to log in a user without password as they click the link for email confirmation? the link contains their EmailConfirmationToken that is generated by the usermanager class
|
0

For those who receive an error from Mr. @heymega's post. The result keyword is missing. The short and correct answer is:

   var user = UserManager.FindByNameAsync(model.UserName).Result;
   try
   {
      await SignInManager.SignInAsync(user, isPersistent:
      false,rememberBrowser:false) ;
            
      return Json(new { success = true, message = "Success" });
   }
   catch (Exception ex)
   {
      return Json(new { success = false, message = "Wrong username" });
   } 

1 Comment

@heymega's answer is correct. If you await the call, there's no need to call into .Result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.