Net Core重置密码令牌和Identity Server 4令牌无效



我的应用程序和API使用IdentityServer 4进行保护。

我有一个集中式的API用于用户管理(注册新用户、更新、删除和重置密码(。identityserver将使用此api生成的令牌来重置用户的密码。

问题是我总是得到无效的令牌错误我知道这与url编码无关,因为忘记的密码由身份服务器处理,身份服务器生成的令牌工作正常。问题是当令牌由不同的api生成时(即使是在一台机器上(。

我曾考虑创建一个通用的数据保护提供商,但我不清楚如何做到这一点基本上,我如何重置一个api创建的密码令牌,让另一个api接受

我正在使用Asp Identity的用户管理器生成重置密码令牌:

var token = await _userManager.GeneratePasswordResetTokenAsync(appUser);

这就是我的Identity Server设置为使用Asp Identity的方式:

services
.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Lockout.AllowedForNewUsers = true;
options.Lockout.DefaultLockoutTimeSpan = new System.TimeSpan(12, 0, 0);
options.Lockout.MaxFailedAccessAttempts = int.Parse(Configuration["MaxFailedAttempts"]);
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
...
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.Authentication.CookieSlidingExpiration = true;
})
.AddAspNetIdentity<ApplicationUser>()
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b =>
b.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
options.DefaultSchema = Globals.SCHEMA_IDS;
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b =>
b.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
options.DefaultSchema = Globals.SCHEMA_IDS;
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30;
})
.AddProfileService<CustomProfileService>()
.AddSigninCredentialFromConfig(Configuration.GetSection("SigninKeyCredentials"), Logger);

这就是我的UserManagementApi如何设置为使用AspIdentity:

services.AddTransient<IUserStore<ApplicationUser>, UserStore<ApplicationUser, IdentityRole, ApplicationDbContext>>();
services.AddTransient<IRoleStore<IdentityRole>, RoleStore<IdentityRole, ApplicationDbContext>>();
services.AddTransient<IPasswordHasher<ApplicationUser>, PasswordHasher<ApplicationUser>>();
services.AddTransient<ILookupNormalizer, UpperInvariantLookupNormalizer>();
services.AddTransient<IdentityErrorDescriber>();
var identityBuilder = new IdentityBuilder(typeof(ApplicationUser), typeof(IdentityRole), services);
identityBuilder.AddTokenProvider("Default", typeof(DataProtectorTokenProvider<ApplicationUser>));
services.AddTransient<UserManager<ApplicationUser>>();

不得不继续讨论其他问题,现在又回到了这个问题。我最终通过确保我的所有API和IdentityServer实例都配置为使用ASP来解决这个问题。NET核心数据保护。我使用redis作为我的分布式缓存系统,所以我只需要配置我的每个api和identityserver,现在在生成令牌时,所有东西都使用相同的密钥。以下是我在每次启动.cs中使用的内容:

public void ConfigureServices(IServiceCollection services)
{
...            
services.AddSession();
services.Configure<RedisConfiguration>(Configuration.GetSection("redis"));
services.AddDistributedRedisCache(options =>
{
options.Configuration = Configuration.GetValue<string>("redis:host");
});
var redis = ConnectionMultiplexer.Connect(Configuration.GetValue<string>("redis:host"));
services.AddDataProtection()
.PersistKeysToRedis(redis, "DataProtection-Keys")
.SetApplicationName(<application name>);
services.AddTransient<ICacheService, CacheService>();
...
}

然后不要忘记使用会话(在API中(:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseAuthentication();
app.UseSession();
...
}

使用会话(在IdentityServer中(:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseIdentityServer();
app.UseSession();
...
}

由于这是一个2个月前的问题,我想你已经提出了。我的建议是:看看你代币的使用寿命。并在你的启动.cs中设置如下:

services.Configure<DataProtectionTokenProviderOptions>(options =>
{
options.TokenLifespan = TimeSpan.FromHours(tokenlifespan); 
});

希望这能帮助你!

我遇到了同样的"无效令牌";ASP上的IdentityServer4问题。NET核心3.1。

Prathamesh Shende在learn.microsoft.com上的回答为我解决了这个问题:

在ResetPassword操作中,在将代码传递给_userManager之前,首先需要对代码进行解码。ResetPasswordAsync方法。像这样:

var decodedCode = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(model.Code));

最新更新