OpenIddict MongoDB 集成
基本配置
要配置 OpenIddict 使用 MongoDB 作为应用程序、授权、范围和令牌的数据库,您需要:
引用 OpenIddict.MongoDb 包:
<PackageReference Include="OpenIddict.MongoDb" Version="5.6.0" />
配置 OpenIddict 使用 MongoDB 存储:
services.AddOpenIddict() .AddCore(options => { // 注意:要使用远程服务器,请调用接受连接字符串或 MongoClientSettings 实例的 MongoClient 构造函数重载。 options.UseMongoDb() .UseDatabase(new MongoClient().GetDatabase("openiddict")); });
或者,您可以将
IMongoDatabase
实例注册为服务:services.AddOpenIddict() .AddCore(options => options.UseMongoDb()); // 注意:要使用远程服务器,请调用接受连接字符串或 MongoClientSettings 实例的 MongoClient 构造函数重载。 services.AddSingleton(new MongoClient().GetDatabase("shared-database-instance"));
创建索引来提高性能(推荐):为此,您可以使用以下脚本来初始化数据库并创建 OpenIddict 实体使用的索引:
using System.Threading; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using MongoDB.Driver; using OpenIddict.MongoDb; using OpenIddict.MongoDb.Models; var services = new ServiceCollection(); services.AddOpenIddict() .AddCore(options => options.UseMongoDb()); services.AddSingleton(new MongoClient("mongodb://localhost:27017").GetDatabase("openiddict")); var provider = services.BuildServiceProvider(); var context = provider.GetRequiredService<IOpenIddictMongoDbContext>(); var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictMongoDbOptions>>().CurrentValue; var database = await context.GetDatabaseAsync(CancellationToken.None); var applications = database.GetCollection<OpenIddictMongoDbApplication>(options.ApplicationsCollectionName); await applications.Indexes.CreateManyAsync( [ new CreateIndexModel<OpenIddictMongoDbApplication>( Builders<OpenIddictMongoDbApplication>.IndexKeys.Ascending(application => application.ClientId), new CreateIndexOptions { Unique = true }), new CreateIndexModel<OpenIddictMongoDbApplication>( Builders<OpenIddictMongoDbApplication>.IndexKeys.Ascending(application => application.PostLogoutRedirectUris), new CreateIndexOptions { Background = true }), new CreateIndexModel<OpenIddictMongoDbApplication>( Builders<OpenIddictMongoDbApplication>.IndexKeys.Ascending(application => application.RedirectUris), new CreateIndexOptions { Background = true }) ]); var authorizations = database.GetCollection<OpenIddictMongoDbAuthorization>(options.AuthorizationsCollectionName); await authorizations.Indexes.CreateOneAsync( new CreateIndexModel<OpenIddictMongoDbAuthorization>( Builders<OpenIddictMongoDbAuthorization>.IndexKeys .Ascending(authorization => authorization.ApplicationId) .Ascending(authorization => authorization.Scopes) .Ascending(authorization => authorization.Status) .Ascending(authorization => authorization.Subject) .Ascending(authorization => authorization.Type), new CreateIndexOptions { Background = true })); var scopes = database.GetCollection<OpenIddictMongoDbScope>(options.ScopesCollectionName); await scopes.Indexes.CreateOneAsync(new CreateIndexModel<OpenIddictMongoDbScope>( Builders<OpenIddictMongoDbScope>.IndexKeys.Ascending(scope => scope.Name), new CreateIndexOptions { Unique = true })); var tokens = database.GetCollection<OpenIddictMongoDbToken>(options.TokensCollectionName); await tokens.Indexes.CreateManyAsync( [ new CreateIndexModel<OpenIddictMongoDbToken>( Builders<OpenIddictMongoDbToken>.IndexKeys.Ascending(token => token.ReferenceId), new CreateIndexOptions<OpenIddictMongoDbToken> { // 注意:部分筛选表达式不被 Azure Cosmos DB 支持。 // 作为解决方法,可以移除表达式和唯一约束。 PartialFilterExpression = Builders<OpenIddictMongoDbToken>.Filter.Exists(token => token.ReferenceId), Unique = true }), new CreateIndexModel<OpenIddictMongoDbToken>( Builders<OpenIddictMongoDbToken>.IndexKeys.Ascending(token => token.AuthorizationId), new CreateIndexOptions<OpenIddictMongoDbToken>() { PartialFilterExpression = Builders<OpenIddictMongoDbToken>.Filter.Exists(token => token.AuthorizationId), }), new CreateIndexModel<OpenIddictMongoDbToken>( Builders<OpenIddictMongoDbToken>.IndexKeys .Ascending(token => token.ApplicationId) .Ascending(token => token.Status) .Ascending(token => token.Subject) .Ascending(token => token.Type), new CreateIndexOptions { Background = true }) ]);
高级配置
使用自定义实体
对于需要在 OpenIddict 使用的属性之外存储额外数据的应用程序,可以使用自定义实体。为此,您需要:
创建自定义实体:
public class CustomApplication : OpenIddictMongoDbApplication { public string CustomProperty { get; set; } } public class CustomAuthorization : OpenIddictMongoDbAuthorization { public string CustomProperty { get; set; } } public class CustomScope : OpenIddictMongoDbScope { public string CustomProperty { get; set; } } public class CustomToken : OpenIddictMongoDbToken { public string CustomProperty { get; set; } }
配置 MongoDB 使用自定义实体:
services.AddOpenIddict()
.AddCore(options =>
{
options.UseMongoDb()
.ReplaceDefaultApplicationEntity<CustomApplication>()
.ReplaceDefaultAuthorizationEntity<CustomAuthorization>()
.ReplaceDefaultScopeEntity<CustomScope>()
.ReplaceDefaultTokenEntity<CustomToken>();
});
使用自定义集合名称
默认情况下,OpenIddict 使用 openiddict.[实体名称]s
模式来确定默认集合名称。需要使用不同集合名称的应用程序可以使用 Set*CollectionName()
辅助方法:
services.AddOpenIddict()
.AddCore(options =>
{
options.UseMongoDb()
.SetApplicationsCollectionName("custom-applications-collection")
.SetAuthorizationsCollectionName("custom-authorizations-collection")
.SetScopesCollectionName("custom-scopes-collection")
.SetTokensCollectionName("custom-tokens-collection");
});