Подтвердить что ты не робот

Identity 2.0 с пользовательскими таблицами

Я новичок в идентификации ASP.NET и все еще пытаюсь понять, как все это работает. К сожалению, я нашел много учебников, которые я пробовал для Identity 1.0, тогда как я пытаюсь работать с Identity 2.0.

Самая большая проблема, с которой я столкнулся, - это то, что я считаю простым, но оказалось, что этого не случилось. То, что я пытаюсь сделать, это использовать существующую базу данных с существующей пользовательской таблицей. В настоящее время все, что я могу сделать, это заставить Identity создавать собственные таблицы для хранения пользовательских данных. Я не хочу использовать Entity Framework, но мне очень трудно отделить Entity Framework от Identity 2.0.

В моей ситуации я использую SQL Server, мне показалось, что я попытаюсь реализовать пользовательский поставщик для MySQL по этой ссылке: http://www.asp.net/identity/overview/extensibility/implementing-a-custom-mysql-aspnet-identity-storage-provider и https://github.com/raquelsa/AspNet.Identity.MySQL. Кажется, что это работает только в Identity 1. Кажется, что он более новый, но использует Entity Framework. Я также пробовал https://github.com/ILMServices/RavenDB.AspNet.Identity.

Со всем, что я пробовал, я застрял в следующей строке:

var manager = new IdentityUserManager(new UserStore<IdentityUser>(context.Get<ApplicationDbContext>()));

Проблема, с которой я сталкиваюсь, заключается в том, что мне нужно удалить класс ApplicaitonDbContext в соответствии с инструкциями для RavenDB, однако я не знаю, что помещать в эту строку.

Я получаю следующие ошибки:

Не общий тип "AspNet.Identity.MySQL.UserStore" не может использоваться с аргументами типа

и

Не удалось найти имя типа или пространства имен 'ApplicationDbContext' (вам не хватает директивы using или ссылки на сборку?)

Ожидается вторая ошибка, однако я не уверен, что использовать в этой строке кода. Кто-нибудь имел опыт внедрения пользовательского поставщика без использования Entity Framework?

Спасибо.

Обновление 1:

Я попытался выполнить следующий учебник [http://aspnetguru.com/customize-authentication-to-your-own-set-of-tables-in-asp-net-mvc-5/], но он оказался неполным, с ошибками компиляции или времени выполнения, точно следуя инструкциям. Несколько проблем, которые у меня есть, - это...

При замене всех экземпляров "ApplicationUser" на "Пользователь" есть проблема со следующей строкой в ​​IdentityConfig.cs

var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<MyDbContext>()));

Изменение ApplicationUser для пользователя вызывает следующую ошибку:

Тип "WebApplicationTest2.Models.User" не может использоваться как параметр типа "TUser" в универсальном типе или методе "Microsoft.AspNet.Identity.EntityFramework.UserStore". Нет никакого неявного преобразования ссылок из "WebApplicationTest2.Models.User" в "Microsoft.AspNet.Identity.EntityFramework.IdentityUser".

Я также затрудняюсь с тем, как использовать пользовательский менеджер и многие методы ASync. Следующие строки не работают:

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, await user.GenerateUserIdentityAsync(UserManager));

В AccountController.cs со следующими ошибками:

Наилучшее перегруженное соответствие метода для "Microsoft.Owin.Security.IAuthenticationManager.SignIn(Microsoft.Owin.Security.AuthenticationProperties, params System.Security.Claims.ClaimsIdentity []) 'содержит некоторые недопустимые аргументы.

"WebApplicationTest2.Models.User" не содержит определения для "GenerateUserIdentityAsync "и не используется метод расширения" GenerateUserIdentityAsync", принимающий первый аргумент типа "WebApplicationTest2.Models.User" (вам не хватает директивы using или ссылка на сборку?)

4b9b3361

Ответ 1

В ваших примерах вы, похоже, хотите заменить DbContext чем-то другим, но я верю, что на самом деле вам нужно сосредоточить усилия на одном уровне выше.

Структура имеет класс UserManager, который несет ответственность за управление, но не хранение, пользователей и их соответствующую информацию. Когда он хочет сохранить пользователей (или их соответствующую информацию), по умолчанию используется предоставленный UserStore<IdentityUser>, который знает, как хранить экземпляры IdentityUser в базе данных с помощью DbContext.

В рамках 2.0 различные биты хранения идентификатора были разбиты на несколько интерфейсов. Представленная по умолчанию реализация UserStore<IdentityUser> реализует некоторые из этих интерфейсов и сохраняет данные для всех в базе данных с помощью DbContext.

Если вы посмотрите на defnition установленного по умолчанию объекта основанного на базе данных объекта UserStore, вы увидите, что он реализует многие из этих небольших интерфейсов:

public class UserStore<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> : IUserLoginStore<TUser, TKey>, 
IUserClaimStore<TUser, TKey>, IUserRoleStore<TUser, TKey>, IUserPasswordStore<TUser, TKey>, 
IUserSecurityStampStore<TUser, TKey>, IQueryableUserStore<TUser, TKey>, IUserEmailStore<TUser, TKey>, 
IUserPhoneNumberStore<TUser, TKey>, IUserTwoFactorStore<TUser, TKey>, IUserLockoutStore<TUser, TKey>, 
IUserStore<TUser, TKey>, IDisposable 
where TUser : IdentityUser<TKey, TUserLogin, TUserRole, TUserClaim>
where TRole : IdentityRole<TKey, TUserRole>
where TKey : Object, IEquatable<TKey>
where TUserLogin : new(), IdentityUserLogin<TKey>
where TUserRole : new(), IdentityUserRole<TKey>
where TUserClaim : new(), IdentityUserClaim<TKey>

Поскольку вы вообще не хотите использовать Entity Framework, вам необходимо предоставить свои собственные реализации некоторых из этих ключевых интерфейсов, которые будут хранить эти данные в тех местах, где вы хотите сохранить данные. Основной интерфейс IUserStore<Tuser,TKey>. это определяет контракт на хранение пользователей, имеющих ключ определенного типа. Если вы хотите хранить пользователей и никакой другой информации, вы можете реализовать этот интерфейс, а затем передать свою реализацию в UserManager, и вам должно быть хорошо идти.

Его маловероятно, что этого будет достаточно, хотя, скорее всего, вам понадобятся пароли, роли, логины и т.д. для ваших пользователей. Если это так, вам нужно сделать свой класс, который реализует IUserStore<Tuser,TKey>, также реализовать IUserPasswordStore<TUser, TKey>, IRoleStore<TRole, TKey> и IUserClaimStore<TUser, TKey>.

Здесь вы можете найти список всех интерфейсов в MSDN

В зависимости от бит, который вы хотите использовать, вам необходимо реализовать эти интерфейсы.

Вероятно, вам также необходимо будет определить собственные версии классов Identity*, которые существуют для инфраструктуры Entity уже вне поля.. Таким образом, вам понадобится ваш собственный класс IdentityUser, который будет перенаправлять пользователей, которых вы хотите сохранить, и IdentityUserClaim для пользователей. Я не сделал этого сам, поэтому я не совсем уверен, но я чувствую, что вам придется это делать.

Скотт Аллен имеет хорошую статью о различных битах модели, которые могут быть полезны.

Что касается ваших проблем с этой строкой:

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, await user.GenerateUserIdentityAsync(UserManager));

Существует метод под названием GenerateUserIdentityAsync, который определен в Applicationuser, который расширяет IdentityUser. Он определен в проекте шаблона, который я считаю, и выглядит примерно так:

public class ApplicationUser : IdentityUser 
{    
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(
    UserManager<ApplicationUser> manager) {
    // Note the authenticationType must match the one 
    // defined in CookieAuthenticationOptions.AuthenticationType
    var userIdentity = 
        await manager.CreateIdentityAsync(this, 
            DefaultAuthenticationTypes.ApplicationCookie);
    // Add custom user claims here
    return userIdentity;
    }
}

Поскольку вы больше не используете инфраструктуру сущности IdentityUser, вам нужно либо определить аналогичный метод, либо свой собственный класс User или implmenet, такую ​​же функциональность каким-либо другим способом (например, просто вызвать await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie))

Ответ 2

Я очень новичок в Identity. Выполняет ли пользовательский объект интерфейс IUser? например.

public partial class User : IUser<Guid> //Whatever your key is
{
    public Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
    {
        return Task.FromResult(GenerateUserIdentity(manager));
    }

    public ClaimsIdentity GenerateUserIdentity(ApplicationUserManager manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = manager.CreateIdentity<User, Guid>(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

Затем, чтобы войти в систему, вы можете позвонить выше:

public async Task SignInAsync(User user, bool isPersistent)
    {
        var userIdentity = await user.GenerateUserIdentityAsync(UserManager);
        AuthenticationManager.SignIn(
            new AuthenticationProperties
            {
                IsPersistent = isPersistent
            },
            userIdentity
        );
    }   

Ответ 3

Я думаю, что это недавно было обновлено до этого в ApplicationUser:

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
{
    // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
    var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
    // Add custom user claims here
    return userIdentity;
}

Он называется так из AccountControllerGetExternalLogin

ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
    OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
    CookieAuthenticationDefaults.AuthenticationType);