迁移到 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 模型的引用
如果应用程序引用了 OpenIddictApplication
、OpenIddictAuthorization
、OpenIddictScope
或 OpenIddictToken
模型,请更新这些引用以使用它们的新名称:
旧名称 | 新名称(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 来序列化或反序列化 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 认证方案的常量已经改变:
旧常量名 | 新常量名(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");
});
});
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 中默认强制执行了新的 响应类型权限。
如果你有许多应用程序需要迁移,你可以使用 此脚本 根据已授予的授权类型推断出适当的响应类型权限。