OpenIddict RC2 is now on NuGet.org

Earlier today, new OpenIddict packages were pushed to NuGet.org:

What's new?

Starting with RC2, using OpenIddict with third-party client applications (i.e applications you don't own and are managed by someone else) is officially supported. For that, new features – that were still work in progress in the previous iterations – have been added:

  • A new application permissions feature was added, which allows controlling and limiting the features a client application can use. For instance, to allow a client application to use only the authorization code flow and the logout endpoint, the following permissions can be granted:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
await _applicationManager.CreateAsync(new OpenIddictApplicationDescriptor
{
ClientId = "mvc",
ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
DisplayName = "MVC client application",
PostLogoutRedirectUris = { new Uri("http://localhost:53507/signout-callback-oidc") },
RedirectUris = { new Uri("http://localhost:53507/signin-oidc") },
Permissions =
{
OpenIddictConstants.Permissions.Endpoints.Authorization,
OpenIddictConstants.Permissions.Endpoints.Logout,
OpenIddictConstants.Permissions.Endpoints.Token,

OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode
}
});

For more information about this feature, you can read the corresponding documentation.

  • A new opt-in scope validation option was added. When it is enabled, OpenIddict automatically rejects authorization and token requests that specify unregistered scopes. Scopes can be registered statically using options.RegisterScopes([list of authorized scopes]) or dynamically, using OpenIddictScopeManager.CreateAsync():
1
2
3
4
5
6
7
8
9
10
11
12
services.AddOpenIddict(options =>
{
// ...

// Mark the "email" and "profile" scopes as valid scopes.
options.RegisterScopes(OpenIdConnectConstants.Scopes.Email,
OpenIdConnectConstants.Scopes.Profile);

// Enable scope validation, so that authorization and token requests
// that specify unregistered scopes are automatically rejected.
options.EnableScopeValidation();
});
1
2
3
4
5
6
await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor
{
Description = "Grants access to the reporting API",
DisplayName = "Reporting API",
Name = "reporting"
});
  • The introspection endpoint was updated to reject access tokens that don't have any audience (since OpenIddict can no longer assume all the registered applications are fully trusted). This change requires updating your code to explicitly attach a resource to your tokens.
1
2
3
4
5
6
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
OpenIdConnectServerDefaults.AuthenticationScheme);

ticket.SetResources("reporting");
  • New OpenIddictScopeManager methods have been introduced to allow associating resources (aka API audiences) with specific scopes and retrieving all the resources corresponding to a set of scopes:
1
2
3
4
5
await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor
{
Name = "reporting",
Resources = { "resource-server-1", "resource-server-2" }
});
1
ticket.SetResources(await _scopeManager.ListResourcesAsync(scopes));
  • New OpenIddictAuthorizationManager methods have been added to make authorizations easier to create or retrieve:
1
2
3
4
5
6
7
8
9
// Create a new permanent authorization associated with
// the specified user and containing the granted scopes:
var authorization = await _authorizationManager.CreateAsync(
principal : ticket.Principal,
subject : await _userManager.GetUserIdAsync(user),
client : await _applicationManager.GetIdAsync(application),
type : OpenIddictConstants.AuthorizationTypes.Permanent,
scopes : ImmutableArray.CreateRange(ticket.GetScopes()),
properties: ImmutableDictionary.CreateRange(ticket.Properties.Items));
1
2
3
4
5
6
7
8
// Retrieve all the permanent and valid authorizations associated
// with the user and containing at least the request scopes:
var authorizations = await _authorizationManager.FindAsync(
subject: _userManager.GetUserId(result.Principal),
client : await _applicationManager.GetIdAsync(application),
status : OpenIddictConstants.Statuses.Valid,
type : OpenIddictConstants.AuthorizationTypes.Permanent,
scopes : ImmutableArray.CreateRange(request.GetScopes()));
  • OpenIddictApplication.RedirectUris, OpenIddictApplication.PostLogoutRedirectUris and OpenIddictAuthorization.Scopes are now serialized as JSON arrays in the database.

Migrate to OpenIddict RC2

Before updating your packages, read the migration guide. It explains how to add an Entity Framework Core migration to update the OpenIddict tables and includes a migration script to convert the RedirectUris, PostLogoutRedirectUris and Scopes columns to the new JSON format.