Маловероятно, что вы найдете рекомендуемую архитектуру для подобного сценария из-за того, как много этой проблемы находится в вашей бизнес-сфере.Кроме того, в библиотеке Identity Server 4 или ее вспомогательных библиотеках нет ничего, что соответствовало бы вашим критериям.
Сказав это, у меня было похожее требование (не связанное с Identity Server 4, но в двух словах идентичные функциональные требования), и должна быть возможность адаптировать ту же идею в вашем случае.
Во-первых, ваша единственная проблема, как вы сказали, заключается в том, что из коробки, используя пакет Edentity Server 4 EF, PersistedGrantStore
использует один IPersistedGrantDbContext
, который выполняет как запись, так и чтение из базы данных.Таким образом, чтобы решить эту проблему, вам необходимо создать собственную реализацию IPersistedGrantStore
, и в этой пользовательской реализации вы можете технически использовать два разных типа DbContext
, один из которых будет создан с использованием строки подключения к одному доступному для записи экземплярубазы данных и будет использоваться только для реализации методов интерфейса, которые выполняют запись, а другой будет использоваться только для методов чтения и будет использовать строку подключения для экземпляра базы данных только для чтения.
Основная идея приведенного выше резюме приведена ниже:
public class MyCustomPersistedGrantStore : IPersistedGrantStore
{
private readonly WriteOnlyPersistedGrantDbContext _writeContext;
private readonly ReadOnlyPersistedGrantDbContext _readContext;
public PersistedGrantStore(WriteOnlyPersistedGrantDbContext writeContext, ReadOnlyPersistedGrantDbContext readContext)
{
_writeContext = writeContext;
_readContext = readContext;
}
public Task StoreAsync(PersistedGrant token)
{
//Use _writeContext to implement storage logic
}
public Task<PersistedGrant> GetAsync(string key)
{
//Use _readContext to implement read logic
}
...other interface methods
}
Все, что вам нужно после реализации вашей пользовательской версии, - это добавить вашу реализацию IPersistedGrantStore
, а также DbContext
в систему DI.
Наконец, этоСтоит отметить, что если вы перестанете использовать .AddOperationalStore(...config)
, то вы также утратите использование TokenCleanupHostService
, поэтому вам также потребуется реализовать это.