项目
版本

迁移到 OpenIddict 3.0

新功能

有关此里程碑中引入变更的公告可在此处找到:这里

重要

迁移到 OpenIddict 3.0 需要对数据库进行更改:现有属性已进行了调整,并添加了新属性以支持新功能。

更新你的包引用

为此,请更新你的 .csproj 文件以引用 OpenIddict.AspNetCore 3.x 元包:

<ItemGroup>
  <PackageReference Include="OpenIddict.AspNetCore" Version="3.1.1" />
  <PackageReference Include="OpenIddict.EntityFrameworkCore" Version="3.1.1" />
</ItemGroup>

确保你的应用程序没有引用遗留/不受支持的包

作为 AspNet.Security.OpenIdConnect.Server 与 OpenIddict 合并的一部分,ASOS 包和 2 个 OpenIddict 包已被标记为遗留且不再受支持。确保你的应用程序(或中间库)没有引用以下任何包:

包名
AspNet.Security.OpenIdConnect.Extensions
AspNet.Security.OpenIdConnect.Primitives
AspNet.Security.OpenIdConnect.Server
Owin.Security.OpenIdConnect.Extensions
Owin.Security.OpenIdConnect.Server
AspNet.Security.OAuth.Introspection
AspNet.Security.OAuth.Validation
Owin.Security.OAuth.Introspection
Owin.Security.OAuth.Validation
OpenIddict.Models
OpenIddict.Mvc
如果应用程序引用了 OpenIdConnectConstants 类,请更新为使用 OpenIddictConstants

更新对 Entity Framework Core/Entity Framework 6/MongoDB 模型的引用

如果应用程序引用了 OpenIddictApplicationOpenIddictAuthorizationOpenIddictScopeOpenIddictToken 模型,请更新这些引用以使用它们的新名称:

旧名称 新名称(Entity Framework Core) 新名称(Entity Framework 6) 新名称(MongoDB)
OpenIddictApplication OpenIddictEntityFrameworkCoreApplication OpenIddictEntityFrameworkApplication OpenIddictMongoDbApplication
OpenIddictAuthorization OpenIddictEntityFrameworkCoreAuthorization OpenIddictEntityFrameworkAuthorization OpenIddictMongoDbAuthorization
OpenIddictScope OpenIddictEntityFrameworkCoreScope OpenIddictEntityFrameworkScope OpenIddictMongoDbScope
OpenIddictToken OpenIddictEntityFrameworkCoreToken OpenIddictEntityFrameworkToken OpenIddictMongoDbToken

在服务器和验证选项中启用 ASP.NET Core 集成

由于基础服务器和验证堆栈与 ASP.NET Core 解耦,你现在必须在服务器/验证选项中显式注册 ASP.NET Core 主机:

services.AddOpenIddict()
    .AddServer(options =>
    {
        options.UseAspNetCore();
    })
    .AddValidation(options =>
    {
        options.UseAspNetCore();
    });

启用授权、注销和令牌端点的直接传递模式

除非你使用 OpenIddict 的事件模型来处理授权、注销和令牌请求,否则你需要为这些端点启用直接传递模式,以便请求可以像以前版本一样到达你的授权控制器:

services.AddOpenIddict()
    .AddServer(options =>
    {
        options.UseAspNetCore()
               .EnableAuthorizationEndpointPassthrough()
               .EnableLogoutEndpointPassthrough()
               .EnableTokenEndpointPassthrough();
    });

启用 ASP.NET Core 数据保护支持以确保现有令牌仍能被验证

为此,在服务器和验证选项中调用 options.UseDataProtection()

services.AddOpenIddict()
    .AddServer(options =>
    {
        options.UseDataProtection();
    })
    .AddValidation(options =>
    {
        options.UseDataProtection();
    });

如适用,请使用新的请求缓存 API

在 3.0 中,启用授权和注销请求的缓存的 OpenIddictServerBuilder.EnableRequestCaching() API 已被两个独立的方法所取代。如果你的应用程序依赖于请求缓存,在迁移到 3.0 时不要忘记启用它:

services.AddOpenIddict()
    .AddServer(options =>
    {
        options.UseAspNetCore()
               .EnableAuthorizationRequestCaching()
               .EnableLogoutRequestCaching();
    });

使用 System.Text.Json 替代 JSON.NET

如果你使用 JSON.NET 来序列化或反序列化 OpenIdConnectMessageOpenIdConnectRequestOpenIdConnectResponse 实例,考虑在迁移到 OpenIddict 3.0 时改用 System.Text.Json,因为 3.0 不再为它们在 3.0 中的等价物(即 OpenIddictMessageOpenIddictRequestOpenIddictResponse)提供内置的 JSON.NET JsonConverter。 在大多数情况下,这应该像替换 JsonConvert.SerializeObject() / JsonConvert.DeserializeObject() 为它们的 System.Text.Json 等价物那么简单: JsonSerializer.Serialize() / JsonSerializer.Deserialize()

替换对 AuthenticationTicket 扩展方法的调用为其新的 ClaimsPrincipal 等价方法

OpenIddict 3.0 不再使用 ASP.NET Core 提供的 AuthenticationTicket 类型。相反,现在所有内容都存储在 ClaimsPrincipal 实例中。如果你有如 ticket.SetScopes()ticket.SetResources() 的调用,请使用它们的新等价物(例如 principal.SetScopes()principal.SetResources())。

使用新的认证方案

在 3.0 中,用于 ASP.NET Core 认证方案的常量已经改变:

旧常量名 新常量名(ASP.NET Core 主机)
OpenIddictServerDefaults.AuthenticationScheme OpenIddictServerAspNetCoreDefaults.AuthenticationScheme
OpenIddictValidationDefaults.AuthenticationScheme OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme
OAuthValidationDefaults.AuthenticationScheme OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme

在 3.0 中,OpenIddict 服务器 ASP.NET Core 处理器支持对 userinfo 请求进行身份验证。因此,如果你使用直接传递模式在自己的 userinfo MVC 操作中处理 userinfo 请求,请考虑为你的 userinfo 端点使用 OpenIddictServerAspNetCoreDefaults.AuthenticationScheme 而不是 OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme,以避免两次验证访问令牌。

更新你的应用程序以适应新的作用域格式

在 OpenIddict 3.0 中,JWT 令牌中使用的 scope 声明的格式已从 JSON 数组更改为单个空格分隔的声明,以匹配JWT 访问令牌规范。为了确保在迁移后你的授权策略仍然有效,请考虑使用 principal.HasScope() 扩展方法来确定是否已授予某个作用域:

services.AddAuthorization(options =>
{
    options.AddPolicy("MyPolicy", builder =>
    {
        builder.RequireAuthenticatedUser();
        builder.RequireAssertion(context => context.User.HasScope("api1"));
    });
});

另外,你可以检查使用与 2.x 相同格式的 OpenIddict 私有 oi_scp 声明(即每个作用域值一个声明)的存在性:

services.AddAuthorization(options =>
{
    options.AddPolicy("MyPolicy", builder =>
    {
        builder.RequireAuthenticatedUser();
        builder.RequireClaim(Claims.Private.Scope, "api1");
    });
});
这两个选项仅适用于 OpenIddict 验证处理器,因为 oi_scp 声明不由 Microsoft 开发的 JWT 承载处理器填充。如果你无法迁移到 OpenIddict 验证处理器,请考虑手动分割标准的 scope 声明以确定它是否包含特定值。

如有必要,添加并应用迁移

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

更新的属性

列名 备注
OpenIddictAuthorizations Subject 此列现可为空以支持设备授权流程。
OpenIddictTokens CreationDate 为了更广泛的数据库支持,此列现在是一个 DateTime 实例。
OpenIddictTokens ExpirationDate 为了更广泛的数据库支持,此列现在是一个 DateTime 实例。
OpenIddictTokens Subject 此列现可为空以支持设备授权流程。

添加的属性

列名 类型 可空
OpenIddictApplications DisplayNames string
OpenIddictApplications Requirements string
OpenIddictAuthorizations CreationDate DateTime
OpenIddictScopes Descriptions string
OpenIddictScopes DisplayNames string
OpenIddictTokens RedemptionDate DateTime

如有必要,在服务器选项中启用混合流支持

在 2.0 中,如果同时启用了授权码和隐式流,则会自动启用混合流。在 3.0 中,情况不再如此,必须明确选择启用混合流。如果你使用混合流,请确保你的应用程序调用了 options.AllowHybridFlow() 方法。

services.AddOpenIddict()
    .AddServer(options =>
    {
        options.AllowHybridFlow();
    });

更新你的应用程序以授予它们适当的响应类型权限

3.0 中默认强制执行了新的 响应类型权限

如果你有许多应用程序需要迁移,你可以使用 此脚本 根据已授予的授权类型推断出适当的响应类型权限。

在本文档中