项目
版本

迁移到 OpenIddict 5.0

有什么新特性?

5.0 版本中最重要的变更可以在 这里 找到。

迁移到 OpenIddict 5.0 需要对数据库进行更改:现有的属性已经重新设计,并添加了新属性以支持新功能。

更新你的包引用

为此,请更新你的 .csproj 文件以引用 OpenIddict 5.x 版本的包。示例:

<ItemGroup>
  <!-- OpenIddict 4.x: -->
  <PackageReference Include="OpenIddict.AspNetCore" Version="4.10.1" />
  <PackageReference Include="OpenIddict.EntityFrameworkCore" Version="4.10.1" />

  <!-- OpenIddict 5.x: -->
  <PackageReference Include="OpenIddict.AspNetCore" Version="5.6.0" />
  <PackageReference Include="OpenIddict.EntityFrameworkCore" Version="5.6.0" />
</ItemGroup>

迁移到 ASP.NET Core 8.0 并非必要,因为 OpenIddict 5.0 依然原生兼容 ASP.NET Core 2.1(仅 .NET Framework)、ASP.NET Core 6.0 和 ASP.NET Core 7.0。迁移到更新的 .NET 运行时或 ASP.NET Core 可以单独进行,以便进行更简单/解耦的升级:

Web 框架版本 .NET 运行时版本
ASP.NET Core 2.1 .NET Framework 4.6.1
ASP.NET Core 2.1 .NET Framework 4.7.2
ASP.NET Core 2.1 .NET Framework 4.8
ASP.NET Core 6.0 .NET 6.0
ASP.NET Core 7.0 .NET 7.0
ASP.NET Core 8.0 .NET 8.0
Microsoft.Owin 4.2 .NET Framework 4.6.1
Microsoft.Owin 4.2 .NET Framework 4.7.2
Microsoft.Owin 4.2 .NET Framework 4.8

使用 OpenIddictApplicationDescriptor.ClientType 代替 OpenIddictApplicationDescriptor.Type

为了避免与新的 OpenIddictApplicationDescriptor.ApplicationType 属性混淆,现有的 OpenIddictApplicationDescriptor.Type 属性已被一个新的 OpenIddictApplicationDescriptor.ClientType 属性所替代。旧属性仍然存在,但现在已过时,并将在下一个主版本中移除。

await manager.CreateAsync(new OpenIddictApplicationDescriptor
{
    ClientId = "mvc",
    ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",

    // Before:
    Type = ClientTypes.Confidential

    // After:
    ClientType = ClientTypes.Confidential
});

如适用,请添加并应用迁移

如果你的应用程序使用 Entity Framework Core 或 Entity Framework 6,请添加一个迁移以应对以下列出的架构变更,并应用它。

新增属性

列名 类型 可空
OpenIddictApplications ApplicationType string
OpenIddictApplications JsonWebKeySet string
OpenIddictApplications Settings string

重命名属性

旧列名 新列名
OpenIddictApplications Type ClientType

如适用,请更新你的 OpenIddict MongoDB 应用程序

为了避免与新的 OpenIddictMongoDbApplication.ApplicationType 属性混淆,现有的 OpenIddictMongoDbApplication.Type 属性已被重命名为 OpenIddictMongoDbApplication.ClientType (在 BSON 模式中为 client_type)。为了确保现有应用程序正确更新以使用新名称,可以使用以下脚本非常高效地一次性更新所有现有应用程序:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using OpenIddict.MongoDb;

var services = new ServiceCollection();
services.AddOpenIddict()
    .AddCore()
    .UseMongoDb()
    .UseDatabase(new MongoClient("mongodb://localhost:27017").GetDatabase("openiddict"));

await using var provider = services.BuildServiceProvider();
var context = provider.GetRequiredService<IOpenIddictMongoDbContext>();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictMongoDbOptions>>().CurrentValue;
var database = await context.GetDatabaseAsync(CancellationToken.None);

var applications = database.GetCollection<BsonDocument>(options.ApplicationsCollectionName);
await applications.UpdateManyAsync(
    filter: Builders<BsonDocument>.Filter.Empty,
    update: Builders<BsonDocument>.Update.Rename("type", "client_type"));

如适用,请更新你的自定义存储以实现新的 API

为了支持 5.0 中引入的新特性,IOpenIddictApplicationStore 新增了一些存储 API,需要你去实现它们:

ValueTask<string?> GetApplicationTypeAsync(TApplication application, CancellationToken cancellationToken);
ValueTask<JsonWebKeySet?> GetJsonWebKeySetAsync(TApplication application, CancellationToken cancellationToken);
ValueTask<ImmutableDictionary<string, string>> GetSettingsAsync(TApplication application, CancellationToken cancellationToken);
ValueTask SetApplicationTypeAsync(TApplication application, string? type, CancellationToken cancellationToken);
ValueTask SetJsonWebKeySetAsync(TApplication application, JsonWebKeySet? set, CancellationToken cancellationToken);
ValueTask SetSettingsAsync(TApplication application, ImmutableDictionary<string, string> settings, CancellationToken cancellationToken);

同时,IOpenIddictTokenStore也新增了一个 API:

ValueTask<long> RevokeByAuthorizationIdAsync(string identifier, CancellationToken cancellationToken);

此外,IOpenIddictAuthorizationStoreIOpenIddictTokenStore 中都存在的 PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken) API 也已更新,现在会返回被移除条目的数量:

// OpenIddict 4.x:
ValueTask PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken);

// OpenIddict 5.x:
ValueTask<long> PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken);

考虑使用客户端断言(可选)

OpenIddict 5.0 在服务器和验证堆栈中引入了对客户端断言的原生支持(在 OpenIddict 4.0 中,客户端断言已经被客户端堆栈支持)。客户端断言提供了比客户端密钥更安全的替代方案,现在是 OpenIddict 5.0 中保密应用程序认证推荐的方式。

欲了解更多信息,请阅读 OpenIddict 5.0 正式发布

在本文档中