openiddict-documentation/guide/migration/20-to-30.md
2021-06-11 17:46:16 +02:00

7.5 KiB

Migrate to OpenIddict 3.0

What's new?

The announcement listing the changes introduced in this milestone can be found here.

Important

Migrating to OpenIddict 3.0 requires making changes to your database: existing properties have been reworked and new ones have been added to support the new features.

Update your packages references

For that, update your .csproj file to reference the OpenIddict.AspNetCore 3.x metapackage:

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

Ensure your application doesn't reference legacy/unsupported packages

As part of the AspNet.Security.OpenIdConnect.Server/OpenIddict merge, the ASOS packages and 2 OpenIddict packages have been marked as legacy and are no longer supported. Make sure your application (or intermediate libraries) don't reference any of these packages:

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

Update the references to the Entity Framework Core/Entity Framework 6/MongoDB models

If your application references the OpenIddictApplication, OpenIddictAuthorization, OpenIddictScope or OpenIddictToken models, update these reference to use their new names: OpenIddict[provider name]Application, OpenIddict[provider name]Authorization, OpenIddict[provider name]Scope and OpenIddict[provider name]Token (e.g when using MongoDB: OpenIddictMongoDbApplication, OpenIddictMongoDbAuthorization, OpenIddictMongoDbScope and OpenIddictMongoDbToken).

Enable ASP.NET Core integration in the server and validation options

With the base server and validation stacks being decoupled from ASP.NET Core, you now have to explicitly register the ASP.NET Core host in the server/validation options:

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

Enable the authorization, logout and token endpoints pass-through mode

Unless you're using OpenIddict's events model to handle authorization, logout and token requests, you'll need to enable the pass-through mode for these endpoints, so that requests can reach your authorization controller as in the previous versions:

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

Enable ASP.NET Core Data Protection support to ensure existing tokens can still be validated

For that, call options.UseDataProtection() in both the server and validation options:

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

Replace JSON.NET by System.Text.Json

If you use JSON.NET to serialize or deserialize OpenIdConnectMessage, OpenIdConnectRequest or OpenIdConnectResponse instances, consider moving to System.Text.Json when migrating to OpenIddict 3.0, as 3.0 no longer includes a built-in JSON.NET JsonConverter for these types.

In most cases, this should be as simple as replacing JsonConvert.SerializeObject()/JsonConvert.DeserializeObject() by their System.Text.Json equivalent: JsonSerializer.Serialize()/JsonSerializer.Deserialize().

Update your application to work with the new scope format

In OpenIddict 3.0, the format of the scope claim used in JWT tokens has changed from a JSON array to a single space-separated claim to match the JWT access token specification. To ensure your authorization policies still work after migrating, consider using the principal.HasScope() extension to determine whether a scope has been granted:

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

Alternatively, you can use the check the presence of the private OpenIddict oi_scp claims that use the same format as in 2.x (i.e one claim per scope value):

services.AddAuthorization(options =>
{
    options.AddPolicy("MyPolicy", builder =>
    {
        builder.RequireAuthenticatedUser();
        builder.RequireClaim(Claims.Private.Scope, "api1");
    });
});

Add and apply migrations, if necessary

If your application uses Entity Framework Core or Entity Framework 6, add a migration to react to the schema changes listed below and apply it.

Updated properties

Table Column name Observations
OpenIddictAuthorizations Subject The column is now nullable to support the device authorization flow.
OpenIddictTokens CreationDate For broader database support, this column is a now a DateTime instance.
OpenIddictTokens ExpirationDate For broader database support, this column is a now a DateTime instance.
OpenIddictTokens Subject The column is now nullable to support the device authorization flow.

Added properties

Table Column name Type Nullable
OpenIddictAuthorizations CreationDate DateTime Yes
OpenIddictTokens RedemptionDate DateTime Yes

If necessary, enable hybrid flow support in the server options

In 2.0, the hybrid flow was automatically enabled if both the authorization code and implicit flows were enabled. In 3.0, this is no longer true and the hybrid flow MUST be explicitly opted in. If you use the hybrid flow, make sure your application calls the options.AllowHybridFlow() method:

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

Update your applications to grant them the appropriate response type permissions

New response type permissions - enforced by default - have been introduced in 3.0.

If you have many applications to migrate, you can use this script to infer appropriate response type permissions using the already granted grant types.