identitysever и AspNetUsers - PullRequest
       43

identitysever и AspNetUsers

0 голосов
/ 09 октября 2018

У меня есть установка, где у меня есть

services.AddIdentity<AppUser, AppRole>() 
    .AddEntityFrameworkStores<ApplicationDbContext>() 
    .AddUserManager<userManage>()
    .AddDefaultTokenProviders();

, где используются AppUser и AppRole, но, похоже, из-за этого происходит сбой.Я продолжаю получать

ArgumentNullException: значение не может быть нулевым.Имя параметра: тип для утверждений в System.Security.Claims.Claim..ctor

после

Microsoft.AspNetCore.Identity.IdentityUserClaim1.ToClaim ()

Весь журнал внизу

Все работало до того, как я ввел расширение для IdentityUser и IdentityRole

для IDS4У меня есть:

        services.AddIdentityServer(options => {
                options.UserInteraction.LoginUrl = "/Account/Login";
            })
           .AddSigningCredential(new X509Certificate2(Path.Combine(".", "certs"
                                                                 , "IdentityServer4Auth.pfx")))
           .AddAspNetIdentity<AppUser>()
           .AddConfigurationStore(options => {
                options.ConfigureDbContext = builder =>
                    builder.UseSqlServer(connection_string, sql => sql.MigrationsAssembly(migrations_assembly));
            })
           .AddOperationalStore(options => {
                //options.DefaultSchema = "token";
                options.ConfigureDbContext = builder =>
                    builder.UseSqlServer(connection_string, sql => sql.MigrationsAssembly(migrations_assembly));
            })
           .AddInMemoryApiResources(Config.GetApiResources())
           .AddInMemoryIdentityResources(Config.GetIdentityResources())
           .AddJwtBearerClientAuthentication()
           .AddProfileService<IdentityProfileService>();

, который работал нормально, но переключился с

         services.AddIdentity<ApplicationUser, IdentityRole>(options =>
        {  })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
        services.AddDistributedMemoryCache();

на

        services.AddIdentity<AppUser, AppRole>()
           .AddEntityFrameworkStores<ApplicationDbContext>()
           .AddUserManager<userManage>()
           .AddDefaultTokenProviders();

и теперь это убивает.Я знаю, что это работает, поскольку AppUser, AppRole и userManage настроены, потому что они одинаковые настройки, используемые во многих моих приложениях, но как только он смешивается с IDS4, он теперь терпит неудачу,Когда он работал, я расширил IdentityUser

public class ApplicationUser : IdentityUser {}

Он тоже работал, это было, когда я смешал 2 приложения вместе, так что оба имели AppUser, AppRole и userManage, когда все пошло плохо. Я приведу нижеприведенные модели

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

    var signin_result = await _signInManager.PasswordSignInAsync(_user, test, model.RememberMe, false);

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

itпользователь утверждает, что

SELECT [uc].[Id], [uc].[ClaimType], [uc].[ClaimValue], [uc].[UserId]
FROM [AspNetUserClaims] AS [uc]
WHERE [uc].[UserId] = @__user_Id_0

, но я не вижу, где проблема, когда это ничего не возвращает с нулевым

log

2018-10-08 13:17:47.164 -07:00 [Information] Entity Framework Core "2.1.4-rtm-31024" initialized '"ApplicationDbContext"' using provider '"Microsoft.EntityFrameworkCore.SqlServer"' with options: "SensitiveDataLoggingEnabled "
2018-10-08 13:17:47.189 -07:00 [Information] Executed DbCommand ("1"ms) [Parameters=["@__user_Id_0='11325643' (Size = 450)"], CommandType='Text', CommandTimeout='30']"
""SELECT [uc].[Id], [uc].[ClaimType], [uc].[ClaimValue], [uc].[UserId]
FROM [AspNetUserClaims] AS [uc]
WHERE [uc].[UserId] = @__user_Id_0"
2018-10-08 13:17:47.370 -07:00 [Error] An exception occurred in the database while iterating the results of a query for context type '"test.app.Data.ApplicationDbContext"'."
""System.ArgumentNullException: Value cannot be null.
Parameter name: type
at System.Security.Claims.Claim..ctor(String type, String value, String valueType, String issuer, String originalIssuer, ClaimsIdentity subject, String propertyKey, String propertyValue)
at System.Security.Claims.Claim..ctor(String type, String value)
at Microsoft.AspNetCore.Identity.IdentityUserClaim`1.ToClaim()
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ProjectionShaper.TypedProjectionShaper`3.Shape(QueryContext queryContext, ValueBuffer& valueBuffer)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ProjectionShaper.TypedProjectionShaper`3.Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.IShaper<TOut>.Shape(QueryContext queryContext, ValueBuffer& valueBuffer)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)"
System.ArgumentNullException: Value cannot be null.
Parameter name: type
at System.Security.Claims.Claim..ctor(String type, String value, String valueType, String issuer, String originalIssuer, ClaimsIdentity subject, String propertyKey, String propertyValue)
at System.Security.Claims.Claim..ctor(String type, String value)
at Microsoft.AspNetCore.Identity.IdentityUserClaim`1.ToClaim()
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ProjectionShaper.TypedProjectionShaper`3.Shape(QueryContext queryContext, ValueBuffer& valueBuffer)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ProjectionShaper.TypedProjectionShaper`3.Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.IShaper<TOut>.Shape(QueryContext queryContext, ValueBuffer& valueBuffer)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
2018-10-08 13:17:48.680 -07:00 [Information] Executed action "WSU.Sso.Controllers.AccountController.Login (test.app)" in 2022.4589ms

Модели и настройки (обратите внимание, что в приложении none IDS4 они работают просто отлично)

public class AppUser : IdentityUser {}
public class AppRole : IdentityRole {}
public class AppUserClaim : IdentityUserClaim<string> {}
public class AppUserRole : IdentityUserRole<string> {}
public class AppRoleClaims : IdentityRoleClaim<string> {}
public partial class CoreDbContext : IdentityDbContext
<
    AppUser, // TUser
    AppRole, // TRole
    string, // TKey
    AppUserClaim, // TUserClaim
    AppUserRole, // TUserRole,
    IdentityUserLogin<string>, // TUserLogin
    AppRoleClaims, // TRoleClaim
    IdentityUserToken<string> // TUserToken
>//, ICoreDbContext
{
    //etc.. 
}

Обновление

Я считаю, что проблема здесь, https://github.com/IdentityServer/IdentityServer4.AspNetIdentity/blob/dev/src/UserClaimsFactory.cs, где UserManager<TUser> userManager должно быть userManage, потому что я это расширил.Кажется, мне нужно сыграть свою собственную роль?

Обновление 2

После удаления userManage расширение UserManager<TUser> получается, что оно по-прежнему не работает с

System.Security.Claims.Claim..ctor (тип строки, строковое значение, строковое valueType, издатель строки, строка originalIssuer, субъект ClaimsIdentity, строковое propertyKey, строковое propertyValue) System.Security.Claims.Claim..ctor (строкатип, строковое значение) Microsoft.AspNetCore.Identity.IdentityUserClaim.ToClaim ()

Была надежда, что упростить это будет ответ, так что мне не пришлось переписывать .AddAspNetIdentity<AppUser>(), но это нене работаетПонятно, что это не что-то, что исходит из БД, которое является нулевым, но должно быть добавлено что-то, чтобы его значение было нулевым.Я не могу сказать, что, просто это должно быть между Microsoft.AspNetCore.Identity.IdentityUserClaim<TKey>.ToClaim() и IdentityServer4.AspNetIdentity.UserClaimsFactory<TUser>.CreateAsync(TUser user) in UserClaimsFactory.cs ... Что я могу точно сказать, это то, что в https://github.com/IdentityServer/IdentityServer4.AspNetIdentity/blob/dev/src/UserClaimsFactory.cs все части, которые пытается установитьпроверяется в БД как не ноль.

Также ничего не стоит, чтобы IDS4 работал до того, как я добавил пользовательскую роль.Я не уверен на 100%, что здесь до сих пор нет игры.

Дополнительное примечание

Так что мне остается задаться вопросом, как я исключаю, является ли это имя ID, что является проблемой здесь.В обновлении таблицы для AspNetUser имеют таблицу, установленную как user_id, а не Id ( Microsoft Owin Security - значение конструктора утверждений не может быть нулевым - это то, что заставляет меня думать об этом).С учетом вышесказанного, я считаю, что в настройке нет ничего плохого, вот что я имею в своем OnModelCreating(ModelBuilder builder),

builder.Entity<AppUser>().Property(p => p.Id).HasColumnName("user_id");

У нас до этого момента не возникало проблем с его использованием, ноЯ устраняю все различия в пользователях, которые могут быть корнем проблемы.

Обновление 3

после перехода через public class IdentityUserClaim<TKey> where TKey : IEquatable<TKey> и установки точки останова на Claim ToClaim() тип равен null.Это что-то вроде лога, но я не могу отследить в стеке вызовов, откуда это происходит.Мой вопрос заключается в том, что если запрос к БД возвращает правильный набор типов и значений, то почему сначала устанавливается нулевой тип и значение для обработки?В самый первый раз, когда достигается точка останова, тип имеет значение null.

ОБНОВЛЕНИЕ 4 основных остановки

после достижения каждой точки останова, я застрял и потерял сознание, если столкнулся с ошибкой здесь.Я вхожу в UserManager и слежу за стеком и вижу, что основные претензии есть и все в порядке.enter image description here

Затем следует запустить хранилище утверждений, которое выполняет указанный выше запрос, и в этот момент происходит сбой.Я не понимаю почему.Я запускаю запрос в SQL Manager, и он в порядке, а не один NULL.enter image description here

Кто-нибудь видит, что происходит? Я сейчас в растерянности.

ОБНОВЛЕНИЕ 5 - сужение

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

enter image description here

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

1 Ответ

0 голосов
/ 12 октября 2018

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

Расширенный IdentityUserClaim<string>, который у меня был, был

public class AppUserClaim : IdentityUserClaim<string>
{
    public int Id { get; set; }

    /// <summary>
    /// Gets or sets the primary key of the user associated with this claim.
    /// </summary>
    public virtual string UserId { get; set; }

    public virtual AppUser user { get; set; }

    /// <summary>
    /// Gets or sets the claim type for this claim.
    /// </summary>
    public virtual string ClaimType { get; set; }

    /// <summary>
    /// Gets or sets the claim value for this claim.
    /// </summary>
    public virtual string ClaimValue { get; set; }

}

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

public class AppUserClaim : IdentityUserClaim<string>  {
    public virtual AppUser user { get; set; } // note this is the reason why i had to extend

}

Решает проблему.Он не появлялся в других приложениях, потому что утверждения были заданы из единого входа, поэтому этот метод всегда пропускался.

Уроки, которые я должен запомнить, всегда обращайте внимание на местных жителей при переходе.Мне потребовался целый день, прежде чем я увидел этот момент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...