迁移到 OpenIddict 3.0
新特性
此版本引入的变更公告可以在这里找到。
IMPORTANT
迁移到 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 包已被标记为过时且不再受支持。确保您的应用程序(或中间库)不引用以下任何包:
| Package name |
|---|
| 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 |
IMPORTANT
如果您的应用程序引用了 OpenIdConnectConstants 类,请更新为使用 OpenIddictConstants。
更新对 Entity Framework Core/Entity Framework 6/MongoDB 模型的引用
如果您的应用程序引用了 OpenIddictApplication、OpenIddictAuthorization、OpenIddictScope 或 OpenIddictToken 模型,请更新这些引用以使用它们的新名称:
| Old name | New name (Entity Framework Core) | New name (Entity Framework 6) | New name (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(为授权和注销请求启用请求缓存)已被 2 个单独的方法取代。如果您的应用程序依赖于请求缓存,在迁移到 3.0 时不要忘记启用它:
services.AddOpenIddict()
.AddServer(options =>
{
options.UseAspNetCore()
.EnableAuthorizationRequestCaching()
.EnableLogoutRequestCaching();
});用 System.Text.Json 替换 JSON.NET
如果您使用 JSON.NET 来序列化或反序列化 OpenIdConnectMessage、OpenIdConnectRequest 或 OpenIdConnectResponse 实例,在迁移到 OpenIddict 3.0 时考虑迁移到 System.Text.Json,因为 3.0 不再包含用于它们的 3.0 等效项(即 OpenIddictMessage、OpenIddictRequest 和 OpenIddictResponse)的内置 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 身份验证方案的常量已更改:
| Old constant name | New constant name (ASP.NET Core host) |
|---|---|
| OpenIddictServerDefaults.AuthenticationScheme | OpenIddictServerAspNetCoreDefaults.AuthenticationScheme |
| OpenIddictValidationDefaults.AuthenticationScheme | OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme |
| OAuthValidationDefaults.AuthenticationScheme | OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme |
NOTE
在 3.0 中,OpenIddict 服务器 ASP.NET Core 处理程序支持验证用户信息请求。因此,如果您使用直通模式在您自己的用户信息 MVC 操作中处理用户信息请求,请考虑为您的用户信息端点使用 OpenIddictServerAspNetCoreDefaults.AuthenticationScheme 而不是 OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme,以避免重复验证访问令牌。
更新您的应用程序以使用新的 scope 格式
在 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"));
});
});或者,您可以使用检查 OpenIddict 私有 oi_scp 声明的存在,这些声明使用与 2.x 相同的格式(即每个范围值一个声明):
services.AddAuthorization(options =>
{
options.AddPolicy("MyPolicy", builder =>
{
builder.RequireAuthenticatedUser();
builder.RequireClaim(Claims.Private.Scope, "api1");
});
});CAUTION
这两个选项仅适用于 OpenIddict 验证处理程序,因为 Microsoft 开发的 JWT 持有者处理程序不会填充 oi_scp 声明。如果您无法迁移到 OpenIddict 验证处理程序,请考虑手动拆分标准 scope 声明以确定它是否包含特定值。
添加和应用迁移(如果需要)
如果您的应用程序使用 Entity Framework Core 或 Entity Framework 6,请添加迁移以响应下面列出的架构更改并应用它。
更新的属性
| 表 | 列名 | 说明 |
|---|---|---|
| OpenIddictAuthorizations | Subject | 该列现在可以为空以支持设备授权流。 |
| OpenIddictTokens | CreationDate | 为了更广泛的数据库支持,此列现在是一个 DateTime 实例。 |
| OpenIddictTokens | ExpirationDate | 为了更广泛的数据库支持,此列现在是一个 DateTime 实例。 |
| OpenIddictTokens | Subject | 该列现在可以为空以支持设备授权流。 |
添加的属性
| 表 | 列名 | 类型 | 可为空 |
|---|---|---|---|
| OpenIddictApplications | DisplayNames | string | Yes |
| OpenIddictApplications | Requirements | string | Yes |
| OpenIddictAuthorizations | CreationDate | DateTime | Yes |
| OpenIddictScopes | Descriptions | string | Yes |
| OpenIddictScopes | DisplayNames | string | Yes |
| OpenIddictTokens | RedemptionDate | DateTime | Yes |
如果需要,在服务器选项中启用混合流支持
在 2.0 中,如果同时启用了授权代码和隐式流,则混合流会自动启用。在 3.0 中,这不再成立,混合流必须明确选择加入。如果您使用混合流,请确保您的应用程序调用 options.AllowHybridFlow() 方法:
services.AddOpenIddict()
.AddServer(options =>
{
options.AllowHybridFlow();
});更新您的应用程序以授予它们适当的响应类型权限
新的响应类型权限 - 默认强制执行 - 已在 3.0 中引入。
NOTE
如果您有许多应用程序需要迁移,可以使用此脚本使用已授予的授权类型推断适当的响应类型权限。
