我有一个地方
services.AddIdentity<AppUser, AppRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddUserManager<userManage>()
.AddDefaultTokenProviders();
使用
AppUser
和
AppRole
的地方,但是似乎因此失败。我不断
ArgumentNullException:值不能为null。参数名称: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 {}
该工具也可以正常工作,那是我将这两个应用程序混合在一起的时候,所以当它们变坏时,它们都有
AppUser
,
AppRole
和
userManage
。我将模型放在下面
另外,我也遵循了日志,在这里杀了我的是数据库中运行的查询正确。当我运行它时,我看不到任何类型值的空值。为了安全起见,我什至在数据库中清除了所有声明区域中的任何空值,例如角色或用户级别。我在导致故障的区域上设置了一个断点,
var signin_result = await _signInManager.PasswordSignInAsync(_user, test, model.RememberMe, false);
当我查看_user时,我看到它具有安全标记,并且所有值都正确填充
它是在用户声明
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.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
模型,并进行设置(请注意,在无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>()
,但是那没有用。显然,不是来自DB的东西为null,而是必须加上它的值为null的东西。我不能说什么,只是它必须在
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中,所有要设置的部分均已通过验证DB为非null。
在添加自定义角色之前IDS4仍在工作,这也不值得。我不是100%不确定这里是否还在发挥作用。
边注
因此,我排除了某些问题,想知道是否是ID的名称成为问题所在。在更新中,AspNetUser的表的表设置为
user_id
而不是
Id
(
Microsoft Owin Security - Claims Constructor Value cannot be null是导致我考虑这一点的原因)。话虽如此,我相信设置没有问题,这就是我
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。
UPDATE 4主要停止
到达每个断点后,如果我在这里遇到错误,我现在会陷入困境并受伤。我进入
UserManager
并遵循堆栈,可以看到主要声明在那里并且可以。
然后下一部分是运行声明存储,该存储执行上面的查询,并在该时间执行失败。我不明白为什么。我在SQL Manager中运行查询,没关系,没有一个
NULL
。
有人看到发生了什么吗?我现在不知所措。
更新5-缩小范围
因此,当我打断设置为null的声明时,没有注意到本地人,我看到我想要的值在
this
的范围内
现在的问题是范围如何关闭,我在错误的位置放置了想要的值
我是一名优秀的程序员,十分优秀!