令牌中的自定义属性
custom properties within token
我发现 OpenIddictToken
有 Properties
和 Payload
字段。据我了解,可以由自定义数据填充,这些数据将保留在数据库中但不会发送给客户端。但是我找不到我应该如何 write/read 这些属性?我看到我可以为 AuthenticationTicket
提供自定义属性,但它似乎是完全不同的属性。
使用这些属性的正确方法是什么?
Properties
列 - 所有 OpenIddict 实体共有 - 确实意味着用作非基本属性的通用包,它允许存储数据而无需更改模式。使用默认管理器不能直接访问属性。相反,我们鼓励您创建自己的从内置管理器派生的管理器,并使用 Store.GetPropertiesAsync()
/Store.SetPropertiesAsync()
访问属性。
OrchardCore 的 OpenID 模块有一个自定义应用程序管理器,使用它来存储应用程序角色,因此您可以查看源代码以了解它们的使用方式: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
列用于存储引用标记,并不意味着用于存储其他数据。
值得注意的是,如果您想存储将保密的数据,有一个简单的选项:如果您不将访问 token/identity 令牌目的地添加到您的私人声明中,它们将不会保留在 access/identity 令牌中,并且只会出现在授权 codes/refresh 令牌中,这些令牌始终是加密的,客户端无法读取。
真的,OpenIddictAuthorizationManager
的行为确实很奇怪 PopulateAsync
function:
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>>();
我发现 OpenIddictToken
有 Properties
和 Payload
字段。据我了解,可以由自定义数据填充,这些数据将保留在数据库中但不会发送给客户端。但是我找不到我应该如何 write/read 这些属性?我看到我可以为 AuthenticationTicket
提供自定义属性,但它似乎是完全不同的属性。
使用这些属性的正确方法是什么?
Properties
列 - 所有 OpenIddict 实体共有 - 确实意味着用作非基本属性的通用包,它允许存储数据而无需更改模式。使用默认管理器不能直接访问属性。相反,我们鼓励您创建自己的从内置管理器派生的管理器,并使用 Store.GetPropertiesAsync()
/Store.SetPropertiesAsync()
访问属性。
OrchardCore 的 OpenID 模块有一个自定义应用程序管理器,使用它来存储应用程序角色,因此您可以查看源代码以了解它们的使用方式: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
列用于存储引用标记,并不意味着用于存储其他数据。
值得注意的是,如果您想存储将保密的数据,有一个简单的选项:如果您不将访问 token/identity 令牌目的地添加到您的私人声明中,它们将不会保留在 access/identity 令牌中,并且只会出现在授权 codes/refresh 令牌中,这些令牌始终是加密的,客户端无法读取。
真的,OpenIddictAuthorizationManager
的行为确实很奇怪 PopulateAsync
function:
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>>();