пользовательские свойства в токене - PullRequest
1 голос
/ 20 февраля 2020

Я обнаружил, что OpenIddictToken имеет поля Properties и Payload. Как я понимаю, это может быть заполнено пользовательскими данными, которые будут сохранены в базе данных, но не будут отправлены клиенту. Но я не могу найти, как мне написать / прочитать эти свойства? Я видел, что могу предоставить пользовательские свойства для AuthenticationTicket, но, похоже, это совершенно другие свойства. Как правильно работать с этими свойствами?

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Столбец Properties - общий для всех сущностей OpenIddict - действительно предназначен для использования в качестве универсального c пакета для несущественных свойств, который позволяет хранить данные без необходимости изменения схемы. Свойства не доступны напрямую с помощью менеджеров по умолчанию. Вместо этого вам предлагается создать собственный менеджер, производный от встроенного, и использовать Store.GetPropertiesAsync() / Store.SetPropertiesAsync() для доступа к свойствам.

В модуле OpenID OrchardCore есть специальный менеджер приложений, который использует его для хранить роли приложений, чтобы вы могли взглянуть на исходный код и посмотреть, как они используются: https://github.com/OrchardCMS/OrchardCore/blob/dev/src/OrchardCore/OrchardCore.OpenId.Core/Services/Managers/OpenIdApplicationManager.cs#L86 -L92

Примечание : в OpenIddict 3.0, Store.GetPropertiesAsync() / Store.SetPropertiesAsync() были обновлены для использования System.Text.Json вместо JSON. NET.


Столбец Payload используется для хранения ссылочных токенов и не предназначен для использования для хранения дополнительных данных.


Стоит отметить, что есть простой вариант, если вы хотите хранить данные, которые будут храниться в частном порядке: если вы не добавите места назначения токена / идентификатора токена в свой личный претензии, они не будут сохранены в токенах доступа / идентификации и будут присутствовать только в кодах авторизации / refre sh, которые всегда зашифрованы и не могут быть прочитаны клиентом.

0 голосов
/ 22 февраля 2020

На самом деле это выглядит как очень странное поведение OpenIddictAuthorizationManager, в частности PopulateAsync, функция :

await Store.SetApplicationIdAsync(authorization, descriptor.ApplicationId, cancellationToken);
await Store.SetScopesAsync(authorization, ImmutableArray.CreateRange(descriptor.Scopes), cancellationToken);
await Store.SetStatusAsync(authorization, descriptor.Status, cancellationToken);
await Store.SetSubjectAsync(authorization, descriptor.Subject, cancellationToken);
await Store.SetTypeAsync(authorization, descriptor.Type, cancellationToken);

, она заполняет все, кроме свойств. Итак, вот что я сделал, чтобы сохранить свойства в базе данных. Сначала я добавил нужные мне свойства на этапе авторизации /connect/authorize:

var ticket = new AuthenticationTicket(
  principal,
  new AuthenticationProperties(new Dictionary<string, string>{ { "name", "value" } }),
  OpenIddictServerDefaults.AuthenticationScheme);

, а затем, как предложено в ответе выше, я создал свой собственный крошечный менеджер аутентификации:

public class AuthorizationManager<TAuthorization>: OpenIddictAuthorizationManager<TAuthorization> where TAuthorization : OpenIddict.MongoDb.Models.OpenIddictAuthorization
    {
        public AuthorizationManager(...): base(cache, resolver, logger, options)
        {
        }

        public async override Task PopulateAsync(
            [NotNull] TAuthorization authorization,
            [NotNull] OpenIddictAuthorizationDescriptor descriptor,
            CancellationToken cancellationToken = default)
        {
            await base.PopulateAsync(authorization, descriptor, cancellationToken);
            if (descriptor.Properties.Any())
            {
                authorization.Properties = new MongoDB.Bson.BsonDocument(
                    descriptor.Properties.Where(p => p.Key[0] != '.') // skip scopes and other technical fields
                    .Select(p => new MongoDB.Bson.BsonElement(p.Key, p.Value))
                    );
            }
        }
    }

, где я заполнил все свойства. И, наконец, я только что включил моего менеджера:

options.ReplaceAuthorizationManager<Services.OpenId.AuthorizationManager<OpenIddictAuthorization>>();
...