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» на «User» возникает проблема со следующей строкой в ​​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 или ссылки на сборку? ?)


person joshhendo    schedule 26.06.2014    source источник


Ответы (3)


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

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

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

Если вы посмотрите на определение предоставленной по умолчанию инфраструктуры сущностей на основе 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 Framework. Поэтому вам понадобится собственный класс 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, либо реализовать ту же функциональность каким-то другим способом (например, просто вызвать await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie) вместо этого).

person Sam Holder    schedule 06.07.2014
comment
Похоже, это лучший шанс, который у меня есть, и он выглядит очень многообещающе, а срок действия награды подходит к концу, поэтому я отдал ее вам. Спасибо. - person joshhendo; 07.07.2014
comment
Джош, ты смог заставить это работать? Я смотрю на то же самое прямо сейчас. - person dmikester1; 13.11.2014
comment
Эта статья мне очень помог. - person Steve Wilford; 20.08.2015
comment
Здесь есть очень хорошая статья: jamessturtevant.com/posts/ASPNET -Identity2.0-Пользовательская база данных - person Dasith Wijes; 12.04.2016

Я довольно новичок в Identity. Реализует ли ваша сущность User интерфейс 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
        );
    }   
person Jenkie    schedule 03.07.2014

Я думаю, что это было недавно обновлено до этого в 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;
}

Вызывается так от AccountController -> GetExternalLogin

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