- Match the ASP.NET Core provider, which keeps the key id and key ring location out of the log
- Assert the provider the manager uses, not only the one the key's descriptor hands out
@ -151,7 +151,7 @@ Add a navigation property to the principal entity if you rely on the previous be
- The provider options classes derive from `AbpDataProtectionTokenProviderOptions` instead of `DataProtectionTokenProviderOptions`. The `Name` and `TokenLifespan` properties are unchanged, but code that assigns one of them to `DataProtectionTokenProviderOptions`, passes it to a method taking that type, returns it, or uses it as a generic constraint no longer compiles.
- `IdentityUserManagerSingleActiveTokenExtensions` moved with the providers, and its `Remove*TokenAsync` helpers changed in two ways. They now follow the provider's options `Name` instead of the key it is registered under, so an application that renamed a provider gets the hash it actually wrote removed. And they throw an `AbpException` instead of reporting success when the key is not served by an `AbpSingleActiveTokenProvider`, which is the case once the ABP providers are turned off: there is no stored hash to remove then, and a token that was never single-active cannot be revoked this way.
- The constructors changed accordingly. `AbpSingleActiveTokenProvider` takes `IOptions<AbpDataProtectionTokenProviderOptions>`, which each provider satisfies with its own concrete options class, and `ILogger<AbpSingleActiveTokenProvider>` instead of `IOptions<DataProtectionTokenProviderOptions>` and `ILogger<DataProtectorTokenProvider<IdentityUser>>`. The five DataProtector-based providers (`AbpDefaultTokenProvider`, `AbpPasswordResetTokenProvider`, `AbpEmailConfirmationTokenProvider`, `AbpChangeEmailTokenProvider`, `LinkUserTokenProvider`) take the new logger type as well. The email and phone 2FA providers moved unchanged. Constructing a provider by hand also behaves differently at the edges: a null options now throws instead of falling back to the ASP.NET Core defaults, which carry the wrong provider name, and a null logger falls back to `NullLogger` instead of throwing.
- `AbpIdentityDomainModule` calls `AddDataProtection()`, because `UserManager` instantiates every provider in `Tokens.ProviderMap` when it is resolved and the DataProtector-based providers need `IDataProtectionProvider`. Hosts that never issue a token, such as a DbMigrator console application, do not register it themselves, and now load the key ring on startup and create one if the store is empty. That is a side effect for such a host, not a reason to configure it: only a host that generates or validates a token needs the same key ring and `SetApplicationName` as the rest of the solution.
- `AbpIdentityDomainModule` calls `AddDataProtection()`, because `UserManager` instantiates every provider in `Tokens.ProviderMap` when it is resolved and the DataProtector-based providers need `IDataProtectionProvider`. Hosts that never issue a token, such as a DbMigrator console application, do not register it themselves. Data Protection registers a hosted service that loads the key ring when the host starts and creates one if the store is empty, so such a host now does that too. That is a side effect for such a host, not a reason to configure it: only a host that generates or validates a token needs the same key ring and `SetApplicationName` as the rest of the solution.
@ -185,9 +185,11 @@ public abstract class AbpSingleActiveTokenProvider : IUserTwoFactorTokenProvider
returnfalse;
}
}
catch(Exceptionex)
catch(Exception)
{
Logger.LogDebug(ex,"Could not read the '{ProviderName}' token. It was protected under another provider name, key ring or application name, or the payload is not a token this provider produced.",Options.Name);
// Without the exception, the way ASP.NET Core's provider logs this: it carries the key id and
// the key ring location.
Logger.LogDebug("Could not read the '{ProviderName}' token. It was protected under another provider name, key ring or application name, or the payload is not a token this provider produced.",Options.Name);