简体   繁体   中英

Double registration(As User/As Company)

I write a new ASP.NET MVC 5 application and I have some problems with the authentication. I want to have two registration and login forms (for users and for companies). I use the basic table ApplicationUser for Users and make my own table CompaniesAccountModel for companies. But the problem comes when I use the UserManager and SignInManager. I can't modify them to work with CompaniesAccountModel. Here you are some code.

[AllowAnonymous]
public ActionResult CompanyRegister()
{
    return View();
}

//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult CompanyRegister([Bind(Include = "CompanyName, Password, Email, ConfirmPassword")] CompanyAccountModel model)
{
     if (ModelState.IsValid)
     {
         db.CompanyAccountModels.Add(model);
         db.SaveChanges();

         return RedirectToAction("Index", "Home");
     }

     // If we got this far, something failed, redisplay form
     return View(model);
}

and

[AllowAnonymous]
public ActionResult CompanyLogin(string returnUrl)
{
    ViewBag.ReturnUrl = returnUrl;
    return View();
}

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

    // This doesn't count login failures towards account lockout
    // To enable password failures to trigger account lockout, change to shouldLockout: true
    var result = await SignInManager.PasswordSignInAsync(model.CompanyName, model.Password, model.RememberMe, shouldLockout: false);
    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);
    }
}

I want to use the UserManager and SignInManager for the companies registration and login. If someone have an idea how to do this, it would be well.

You could easily customize authentication process for your company users. And use it side by side with existing method for ordinary users. Consider this example as a clue:

public ActionResoult CompanyLogin(CompanyLoginViewModel model, string returnUrl)
{
    // imaging you have own company manager, completely independent from identity
    // you could check validity of company by own preferred logic  
    if(_companyManager.IsValid(model))         
    {
        // company is valid, going to authenticate
        var ident = new ClaimsIdentity(
        new[] 
        {
            // adding following 2 claim just for supporting default antiforgery provider
            new Claim(ClaimTypes.NameIdentifier, model.CompanyName),
            new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),

            // an optional claim you could omit this 
            new Claim(ClaimTypes.Name, model.CompanyName),
            // add this role to differentiate from ordinary users
            new Claim(ClaimTypes.Role, "Company"),                 
            // you could even add some role
            new Claim(ClaimTypes.Role, "AnotherRole"),
            // and so on
        },
        DefaultAuthenticationTypes.ApplicationCookie);

        // Identity is sign in user based on claim don't matter 
        // how you generated it Identity 
        HttpContext.GetOwinContext().Authentication.SignIn(
            new AuthenticationProperties { IsPersistent = false }, ident);

        // auth is succeed, 
        return RedirectToAction("MyAction"); 
     }
     ModelState.AddModelError("", "We could not authorize you :(");
     return View();
} 

Since we injected our logic to Identity, we don't need to do extra thing at all.

[Authorize]
public ActionResult MySecretAction()
{
    // all authorized users could use this method don't matter how has been authenticated
    // we have access current user principal by calling also
    // HttpContext.User
 }

 [Authorize(Roles="Company")]
 public ActionResult MySecretAction()
 {
     // just companies have accesses to this method
 }

Also if both ApplicationUser and Company classes share lots in common you could just extend Company from ApplicationUser . By doing so you don't need to write extra login method. Same login works for both. But if for any reason you don't want inherit Company from ApplicationUser my above solution more desirable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM