mihai
mihai

Reputation: 2824

Authentication ASP.NET MVC 5 against Database

I am new to ASP NET MVC authentication and I have troubles with it on my web Project

By default (as result of project generation) there is an AccountController which has a Login method

[Authorize]
public class AccountController : Controller
{
    private UserService _userService;
    public UserService UserService{
        get { return _userService ?? (_userService = new UserService()); }
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl){
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        //the line with SignInManager is Default in project
        //var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);

        //I have implemented my User service which checks in DB is there exists such a user with email and password and returns the same SignInStatus
        var result = UserService.Authenticate(model.Email, model.Password);

        switch (result)
        {
            case SignInStatus.Success:
                return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresVerification:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
            case SignInStatus.Failure:
            default:
                ModelState.AddModelError("", "Invalid login attempt.");
                return View(model);
        }
    }
}

My UserService implementation:

public class UserService : IUserService
{
    public SignInStatus Authenticate(string email, string password)
    {
        if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password))
        {
            return SignInStatus.Failure;
        }

        //TODO: perform authentication against DB account
        if (email == "[email protected]" && password == "123")
        {
            return SignInStatus.Success;
        }
        else
        {
            return SignInStatus.Failure;
        }
    }
}

I am using it with [Authorize] attribute on my AdministrationController

public class AdministrationController : Controller
{
    // GET: Admin/Admin
    [Authorize]
    public ActionResult Index()
    {
        return View();
    }
}

When I enter the administration area of my site , via http://localhost:53194/administration it does not require any authentication (does not display Login screen)

If I set the attribute [Authorize(Roles = "Administrator")] on my method

public class AdministrationController : Controller
{
    // GET: Admin/Admin
    [Authorize(Roles = "Administrator")]
    public ActionResult Index()
    {
        return View();
    }
}

Login screen appears. I set the email and password. Pressing on Login button it enters the Login method from AccountController, enters the case with SignInStatus.Success

But also the Login screen remains. It is not redirected to normal Administration screen.

Can you advice me how to implement this Authentication please. Thanks.

Upvotes: 0

Views: 734

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039498

You don't seem to have set the authentication cookie upon successful login. So the user actually gets redirected to the Administration page but since he doesn't have a valid authentication cookie, he gets redirected back to the login form.

So make sure that you set the cookie:

case SignInStatus.Success:
    var user = new ApplicationUser
    {
        Email = model.Email,
        UserName = model.Email,
        ... set any other properties that you find convenient
    };
    await SignInManager.SignInAsync(user, false, false);
    return RedirectToLocal(returnUrl);

Upvotes: 1

Related Questions