Идентификация ASP.NET - индивидуальная реализация с использованием нескольких провайдеров

В настоящее время я работаю над большим проектом для автосалонов, и у меня есть дилемма.

Должен ли я использовать идентификатор ASP.NET или старую школу FormsAuthentication?

Мне нужно иметь возможность входа через 2 провайдера. Во-первых, пользователь всегда находится в базе данных, но мы проверяем, является ли он пользователем LDAP, если это так, аутентифицировать его через LDAP (я использую WebService для того, у кого есть метод входа).

Здесь мой метод входа:

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginModel model)
    {
        if (ModelState.IsValid)
        {
            var userInDb = this.db.Users.FirstOrDefault(u => u.Username == model.username);

            if (userInDb != null)
            {
                // USER EXISTS
                if (userInDb.IsLdap)
                {
                    try
                    {
                        // IS LDAP POWERED, IGNORE PASSWORD IN DB
                        using (var ws = WebServiceClient.Factory(model.GetDomain()))
                        {
                            // MAKE AUTH
                            var result = await ws.Login(model.GetUsername(), model.password);

                            if (result.Success)
                            {
                                // USER IS LEGAL
                                FormsAuthentication.SetAuthCookie(model.username, model.remember);

                                return RedirectToAction("Init");
                            }
                            else
                            {
                                // USER IS ILLEGAL
                                ModelState.AddModelError("", "Username or password invalid.");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // AN ERROR OCCURED IN CREATION OF THE WebService
                        ErrorUtils.Send(ex);

                        ModelState.AddModelError("", ex.Message);
                    }
                }
                else
                {
                    // USER IS DB POWERED, CHECK THE PASSWORDS
                    var currentHash = userInDb.Password;

                    var isPasswordOkay = PasswordUtils.Validate(model.password, currentHash);
                    if (isPasswordOkay)
                    {
                        // USER PASSWORD IS LEGIT
                        FormsAuthentication.SetAuthCookie(model.username, model.remember);

                        return RedirectToAction("Init");
                    }
                    else
                    {
                        // BAD PASSWORD
                        ModelState.AddModelError("", "Username or password invalid.");
                    }
                }
            }
            else
            {
                try
                {
                    // USER DO NOT EXISTS IN DB
                    using (var ws = WebServiceClient.Factory(model.GetDomain()))
                    {
                        // MAKE AUTH
                        var result = await ws.Login(model.GetUsername(), model.password);

                        if (result.Success)
                        {
                            // USER IS LEGAL IN LDAP SO CREATE IT IN DB
                            var ldapUser = (AuthResponse.AuthResponseUser)result.User;

                            var name = ldapUser.DisplayName.Split(' ');
                            var user = new User()
                            {
                                Firstname = name[0],
                                Lastname = name[1],
                                ActivatedAt = DateTime.Now,
                                ModifiedAt = DateTime.Now,
                                Email = model.username,
                                IsLdap = true,
                                Username = model.username,
                                Password = "",
                                Notifications = NotificationType.All
                            };

                            // GET THE DEALER TO ADD IT TO THE USER RIGHT NOW
                            var dealer = this.db.BaseContexts.Find(ws.Dealer.Id);
                            user.BaseContexts.Add(dealer);
                            dealer.Users.Add(user);

                            try
                            {
                                this.db.Users.Add(user);

                                this.db.Entry(user).State = System.Data.Entity.EntityState.Added;
                                this.db.Entry(dealer).State = System.Data.Entity.EntityState.Modified;

                                await this.db.SaveChangesAsync();

                                FormsAuthentication.SetAuthCookie(model.username, model.remember);

                                return RedirectToAction("Init");
                            }
                            catch (Exception ex)
                            {
                                ErrorUtils.Send(ex);

                                ModelState.AddModelError("", "An error occured during user creation.");
                            }
                        }
                        else
                        {
                            // USER IS ILLEGAL
                            ModelState.AddModelError("", "Username or password invalid.");
                        }
                    }
                }
                catch (Exception ex)
                {
                    // AN ERROR OCCURED IN CREATION OF THE WebService
                    ErrorUtils.Send(ex);

                    ModelState.AddModelError("", ex.Message);
                }
            }
        }

        return View(model);
    }

Как я могу его оптимизировать или реализовать идентификатор ASP.NET? Я читал о Multi-Tenant, но я не уверен, что это такое.

Я использую FormsAuth прямо сейчас, и это работает, но, похоже, очень ограничено. Например, создание пользователя затруднено, однако в системе Identity есть UserManager, который очень полезен!

Ясно, что я хочу, чтобы что-то пуленепробиваемое для аутентификации через DB или LDAP в зависимости от свойства (bool)User.IsLdap. Я, однако, о создании небольшого класса, который действует как "Аутентификация", но я не могу найти способ его структурировать и быстро сделать.

РЕДАКТИРОВАТЬ: Я знаю внешних поставщиков для идентификации, но не уверен, могу ли я создать свой собственный с помощью LDAP Auth.

Ответ 1

Использование Идентификация ASP.NET - лучший способ, потому что он использует стек OWIN вместо того, чтобы полагаться на system.web. Это было сделано в основном для выполнения и разделения причин. Также хорошо знать, что новые версии MVC идут следующим образом.

Что вы пытаетесь сделать, это использовать Mixed аутентификацию как форм, так и Windows. Хотя есть много способов сделать это, часто проще всего включить windows auth на веб-сервере, а затем разрешить IIS делать тяжелую работу для вас, что устраняет необходимость в веб-сервисе. Если это направление, на которое вы хотите пойти, вы можете взглянуть на этот похожий вопрос, который должен привести вас в правильном направлении.

Смешанная аутентификация для OWIN

Даже если вы не сделаете это точно так же, как предлагаемое решение, вы в конечном итоге внесете свое собственное промежуточное ПО OWIN, чтобы выполнить свою аутентификацию.