Несколько независимых форм регистрации и регистрации..NET Identity 2.0

Создание нового проекта в MVC 5 инициирует все необходимые классы для обработки ролей и пользователей, и я прекрасно разбираюсь в пользовательских свойствах. Однако я не мог понять, что, по моему сценарию, у меня есть несколько разных типов пользователей, например. Мастер-админы, админы, авторы, продавцы и арендаторы.

Все они имеют разные свойства, а также некоторые общие. Обычно я буду использовать каждое имя и пароль каждого типа в их соответствующих таблицах базы данных. Идентификация ASP.NET довольно заманчива, чтобы иметь централизованное хранилище пользователей с преимуществом управления аутентификацией из коробки простым в использовании способом с результатами действий.

Я прочитал каждый результат из поиска Google, но единственным решением, похожим на мой сценарий, было использование претензий (которые, насколько я понимаю, специально не предназначены для обработки этой конкретной ситуации)

Я блуждаю, если есть способ, которым идентификатор asp.net поддерживает такой сценарий?

Любая помощь будет оценена по достоинству. Спасибо.

Ответ 1

У вас есть два варианта для достижения вашей цели:

  • Использование общего класса ApplicationUser и разделение форм с помощью авторизации Roles. Таким образом, вы можете создать форму с условными входами (ограничить то, что отображается с помощью if(User.IsInRole("UserTypeName")) в бритве) на основе ролей пользователя, используя RoleManager или создать отдельные представления для каждого типа пользователя и разрешить их на стороне контроллера.
  • Использование простого наследования для реализации каждого типа пользователя на основе его свойства.

как:

public class CustomUser: ApplicationUser
{
    ...
}

В таблице AspNetUsers будет столбец "Дискриминатор", который поможет Identity Framework идентифицировать класс, который он должен создать для строки (CustomUser или ApplicationUser). Затем вы можете просто запросить как обычно, или если вы хотите только один тип или другой, вы можете использовать OfType<T> как:

var customUsers = db.Users.OfType<CustomUser>();

Имейте в виду, что любое свойство, которое вы добавляете в унаследованный класс, должно быть nullable. Вы не можете потребовать что-то вроде DateTime on CustomUser, которое требуется на уровне базы данных, поскольку оно предотвращает сохранение ApplicationUser, который не обладает этим свойством. Однако это только проблема на уровне базы данных. Вы все еще можете использовать модели просмотра, чтобы сделать конкретное свойство на CustomUser, требуемое с точки зрения front-end.

Ответ 2

В качестве альтернативы претензиям я бы рекомендовал Роли. Если вы не знаете, как это сделать, читайте дальше.

Если вы создали веб-приложение по умолчанию с MVC, то платформа Entity Framework уже установлена. Предполагая, что вы использовали первые миграции кода, EF также уже настроил вашу базу данных для вас.

В этом процессе он добавит папку Migrations с классом Configuration.cs. Этот файл содержит метод Seed, в котором мы будем вносить изменения.

Сначала добавьте следующие данные в Configuration.cs:

using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity;
using Models; // assuming you have kept to the defaults

Добавьте следующий код в функцию Seed:

var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore);
userManager.UserValidator = new UserValidator<ApplicationUser>(userManager) { AllowOnlyAlphanumericUserNames = false };

Небольшой совет. По умолчанию MVC5 устанавливает пользовательскую систему, основанную на электронной почте. Беспокойно, также по умолчанию UserManager проверяет, что UserName (идентичный электронной почте) не содержит специальных символов (включая @). Следовательно, необходимо отключить это.

Чтобы добавить роль, мы просто делаем:

context.Roles.AddOrUpdate(r => r.Name, new IdentityRole { Name = "MyRoleName" });
context.SaveChanges();  

Чтобы добавить нового пользователя в роль

if (!context.Users.Any(t => t.Email == "[email protected]"))
{
    var user = new ApplicationUser { UserName = "[email protected]", Email = "[email protected]" };
    userManager.Create(user, "Password#1");
    context.SaveChanges();
    userManager.AddToRole(user.Id, "MyRoleName");
}

Чтобы добавить существующего пользователя к роли:

var existingUser = context.Users.Where(u => u.UserName == "[email protected]").FirstOrDefault();
userManager.AddToRoles(existingUser.Id, "MyRoleName");

Чтобы применить эти изменения, просто запустите update-database в окне диспетчера пакетов.

Теперь, когда у вас есть пользователи с ролями, вы можете ограничить любое действие, которое вам нравится, используя атрибут Authorize:

[Authorize(Roles ="MyRoleName")]

Эти атрибуты могут быть установлены на уровне класса (чтобы включить/отключить весь контроллер) или для отдельных действий. Чтобы установить несколько ролей, используйте:

[Authorize(Roles ="MyRoleName, MyOtherRole")]

Обратите внимание, что это означает, что любой, кто имеет какую-либо роль, должным образом разрешен. Если вы хотите разрешить только пользователям, у которых есть две роли, вы должны сделать:

[Authorize(Roles ="MyRoleName")]
[Authorize(Roles ="MyOtherRole")]

Помимо использования ролей для ограничения доступа к вашим контроллерам и действиям, вы также можете использовать их для отображения/скрытия элементов в представлении. Например, используя бритву:

@if (User.IsInRole("Admin"))
{
   <p><a class="btn btn-danger btn-lg btn-block" href="@Url.Action("Index", "Administration")">Admin Area</a></p>
}

Это имеет преимущество не-Admin, пользователи не замечают, что им не хватает!

Ответ 3

Сначала я хочу, чтобы вы создали все желаемые роли, например арендаторы и т.д.

Затем создайте ViewModels, например RegisterViewModel.cs для нескольких независимых регистраций администраторов, арендаторов и т.д.

Затем используйте метод действия Зарегистрировать контроллера AccountController.cs, и если вы хотите, чтобы у пользователя была выбранная роль, вы можете использовать эту единственную строку

    var result = await UserManager.AddToRolesAsync(user.Id, "Tenants");

Теперь для завершения процесса используйте Views Like Register.cshtml.

Позвольте мне объяснить с помощью code.Create класс ViewModel Vendor.cs

      public class VendorViewModel
 {
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }}

Теперь создайте поставщика actionmethod в AccountController.cs

    [Authorize(Roles = "Admin")]
        public async Task<ActionResult> CreateVendor()
        {

            return View();
        }
         [Authorize(Roles = "Admin")]
           [HttpPost]
 public async Task<ActionResult> Vendor(VendorViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
         //Add Vendor role to user
           var role = await UserManager.AddToRolesAsync(user.Id, "Vendor");
 }
                AddErrors(result);
            }

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

Теперь создайте View Vendor.cshtml

          @model IdentitySample.Models.VendorViewModel
@{
    ViewBag.Title = "Vendor";
}

<h2>@ViewBag.Title.</h2>

@using (Html.BeginForm("Vendor", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Create a new account.</h4>
    <hr />
    @Html.ValidationSummary("", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Vendor" />
        </div>
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Создавайте больше, когда вам нужны эти формы.