gpt4 book ai didi

c# - identitysever和AspNetUsers

转载 作者:太空宇宙 更新时间:2023-11-03 14:48:57 27 4
gpt4 key购买 nike

我有一个地方

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


使用 AppUserAppRole的地方,但是似乎因此失败。我不断


  ArgumentNullException:值不能为null。参数名称:System.Security.Claims.Claim..ctor上声明的类型





  Microsoft.AspNetCore.Identity.IdentityUserClaim1.ToClaim()


整个日志在底部

在介绍 IdentityUserIdentityRole的扩展名之前,一切正常

对于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();


现在就杀死了它。我知道它最多可以设置 AppUserAppRoleuserManage,因为它们与我的许多应用程序中使用的设置相同,但是一旦与IDS4混合使用,现在就会失败。在工作时,我已经扩展了 IdentityUser

public class ApplicationUser : IdentityUser {}


该工具也可以正常工作,那是我将这两个应用程序混合在一起的时候,所以当它们变坏时,它们都有 AppUserAppRoleuserManage。我将模型放在下面

另外,我也遵循了日志,在这里杀了我的是数据库中运行的查询正确。当我运行它时,我看不到任何类型值的空值。为了安全起见,我什至在数据库中清除了所有声明区域中的任何空值,例如角色或用户级别。我在导致故障的区域上设置了一个断点,

    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而不是 IdMicrosoft 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并遵循堆栈,可以看到主要声明在那里并且可以。
enter image description here

然后下一部分是运行声明存储,该存储执行上面的查询,并在该时间执行失败。我不明白为什么。我在SQL Manager中运行查询,没关系,没有一个 NULL
enter image description here

有人看到发生了什么吗?我现在不知所措。

更新5-缩小范围

因此,当我打断设置为null的声明时,没有注意到本地人,我看到我想要的值在 this的范围内

enter image description here

现在的问题是范围如何关闭,我在错误的位置放置了想要的值

最佳答案

这个问题花了一些时间解决,但是现在很清楚为什么会失败。 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; }

}


但是 ClaimTypeClaimValue的属性不需要重写。一旦完成此操作,它将在方法范围之外的地方设置值。将模型更改为

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

}


解决问题。它没有出现在其他应用程序中,因为声明是在SSO中设置的,因此始终会跳过该方法。

我要记住的经验教训,请确保在逐步通过时一定要看当地人。我花了一天的时间才看到那一刻。

关于c# - identitysever和AspNetUsers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52710862/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com