Реализация интерфейса IPersistedGrantStore (IdentityServer4)
Всем привет. Я пытаюсь сохранить модифицировать свою программу и сохранять токен не в памяти, а в БД. Для этого я решил реализовать интерфейс IPersistedGrantStore. Сейчас я реализовал все 5 методов. Но есть ощущение, что с ошибками. Можете ли подсказать верную реализацию для этих методов?
using AutoMapper;
using IdentityServer4.Models;
using IdentityServer4.Services;
using IdentityServer4.Stores;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using ServiceStack;
using ServiceStack.Data;
using ServiceStack.OrmLite;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace innRoad.Pms.Identity.Api.Core.DataAccess
{
public class IdentityPersistedGrantStore : IPersistedGrantStore
{
private readonly IDbConnectionFactory _dbConnectionFactory;
private readonly ILogger logger;
public IdentityPersistedGrantStore(IDbConnectionFactory dbConnectionFactory)
{
_dbConnectionFactory = dbConnectionFactory;
this.logger = logger;
}
public async Task<IEnumerable<PersistedGrant>> GetAllAsync(PersistedGrantFilter filter)
{
IEnumerable<PersistedGrantEntity> persistedGrantEntities;
using (var identityConnection = await _dbConnectionFactory.OpenAsync(DbConnectionNames.Identity))
{
persistedGrantEntities = await identityConnection.LoadSelectAsync<PersistedGrantEntity>(x => x.SubjectId == filter.SubjectId);
}
return MapPersistedEntityToPersistedGrant(persistedGrantEntities);
}
public async Task<PersistedGrant> GetAsync(string key)
{
IEnumerable<PersistedGrantEntity> persistedGrantEntities;
using (var identityConnection = await _dbConnectionFactory.OpenAsync(DbConnectionNames.Identity))
{
persistedGrantEntities = await identityConnection.LoadSelectAsync<PersistedGrantEntity>(x => x.Id.Equals(key));
}
return MapPersistedGrant(persistedGrantEntities.FirstOrDefault());
}
public async Task RemoveAllAsync(PersistedGrantFilter filter)
{
using (var identityConnection = await _dbConnectionFactory.OpenAsync(DbConnectionNames.Identity))
{
await identityConnection.DeleteAsync<PersistedGrantEntity>(x =>
x.ClientId == filter.ClientId &&
x.SubjectId == filter.SubjectId);
}
}
public async Task RemoveAsync(string key)
{
using (var identityConnection = await _dbConnectionFactory.OpenAsync(DbConnectionNames.Identity))
{
await identityConnection.DeleteAsync<PersistedGrantEntity>(x => x.Id == key);
}
}
public async Task StoreAsync(PersistedGrant grant)
{
grant.Key = EncodePersistedGrantKey(grant.Key);
var persistedGrantEntity = MapPersistedGrants(grant);
using (var identityConnection = await _dbConnectionFactory.OpenAsync(DbConnectionNames.Identity))
{
identityConnection.CreateTable<PersistedGrantEntity>();
await identityConnection.InsertAsync(persistedGrantEntity);
}
}
private PersistedGrantEntity MapPersistedGrants(PersistedGrant grant)
{
return new PersistedGrantEntity
{
Id = grant.Key,
ClientId = grant.ClientId,
SessionId = grant.SessionId,
ConsumedTime = grant.ConsumedTime,
CreationTime = grant.CreationTime,
Expiration = grant.Expiration,
Data = grant.Data,
Description = grant.Description,
SubjectId = grant.SubjectId,
Type = grant.Type
};
}
private string EncodePersistedGrantKey(string key)
{
key = Base64UrlEncoder.Encode(key);
return key;
}
private PersistedGrant MapPersistedGrant(PersistedGrantEntity persistedGrantEntity)
{
return new PersistedGrant
{
Key = persistedGrantEntity.Id,
ClientId = persistedGrantEntity.ClientId,
SessionId = persistedGrantEntity.SessionId,
ConsumedTime = persistedGrantEntity.ConsumedTime,
CreationTime = persistedGrantEntity.CreationTime,
Expiration = persistedGrantEntity.Expiration,
Data = persistedGrantEntity.Data,
Description = persistedGrantEntity.Description,
SubjectId = persistedGrantEntity.SubjectId,
Type = persistedGrantEntity.Type
};
}
private IEnumerable<PersistedGrant> MapPersistedEntityToPersistedGrant(IEnumerable<PersistedGrantEntity> persistedGrantEntities)
{
var persistedGrant = new List<PersistedGrant>();
foreach (var entityPersistedGrant in persistedGrantEntities)
{
var persisted = new PersistedGrant
{
Key = entityPersistedGrant.Id,
Type = entityPersistedGrant.Type,
SubjectId = entityPersistedGrant.SubjectId,
SessionId = entityPersistedGrant.SessionId,
ClientId = entityPersistedGrant.ClientId,
Description = entityPersistedGrant.Description,
CreationTime = entityPersistedGrant.CreationTime,
Expiration = entityPersistedGrant.Expiration,
ConsumedTime = entityPersistedGrant.ConsumedTime,
Data = entityPersistedGrant.Data
};
persistedGrant.Add(persisted);
}
return persistedGrant;
}
}
}
На данный момент в методе GetAsync я получаю такую ошибку: Conversion failed when converting the varchar value '2jfZz' to data type int.
public async Task<PersistedGrant> GetAsync(string key)
{
IEnumerable<PersistedGrantEntity> persistedGrantEntities;
using (var identityConnection = await _dbConnectionFactory.OpenAsync(DbConnectionNames.Identity))
{
persistedGrantEntities = await identityConnection.LoadSelectAsync<PersistedGrantEntity>(x => x.Id.Equals(key));
}
return MapPersistedGrant(persistedGrantEntities.FirstOrDefault());
}
Хотя я не вижу тут явной конвертации в int. Скорее всего я просто неверно реализовал этот метод. Ошибка в этой строке:
persistedGrantEntities = await identityConnection.LoadSelectAsync<PersistedGrantEntity>(x => x.Id.Equals(key));