/// <summary>
        /// Registers the Entity Framework stores. Note: when using the built-in Entity Framework stores,
        /// the entities MUST be derived from the models contained in the OpenIddict.Models package.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddEntityFrameworkCoreStores<TContext, TKey>([NotNull] this OpenIddictBuilder builder)
            where TContext : DbContext
            where TKey : IEquatable<TKey> {
            if (builder == null) {
                throw new ArgumentNullException(nameof(builder));
            }

            Debug.Assert(builder.ApplicationType != null &&
                         builder.AuthorizationType != null &&
                         builder.ScopeType != null &&
                         builder.TokenType != null, "The entity types exposed by OpenIddictBuilder shouldn't be null.");

            // Register the application store in the DI container.
            builder.Services.TryAddScoped(
                typeof(IOpenIddictApplicationStore<>).MakeGenericType(builder.ApplicationType),
                typeof(OpenIddictApplicationStore<,,,>).MakeGenericType(
                    /* TApplication: */ builder.ApplicationType,
                    /* TToken: */ builder.TokenType,
                    /* TContext: */ typeof(TContext),
                    /* TKey: */ typeof(TKey)));

            // Register the authorization store in the DI container.
            builder.Services.TryAddScoped(
                typeof(IOpenIddictAuthorizationStore<>).MakeGenericType(builder.AuthorizationType),
                typeof(OpenIddictAuthorizationStore<,,,>).MakeGenericType(
                    /* TAuthorization: */ builder.AuthorizationType,
                    /* TToken: */ builder.TokenType,
                    /* TContext: */ typeof(TContext),
                    /* TKey: */ typeof(TKey)));

            // Register the scope store in the DI container.
            builder.Services.TryAddScoped(
                typeof(IOpenIddictScopeStore<>).MakeGenericType(builder.ScopeType),
                typeof(OpenIddictScopeStore<,,>).MakeGenericType(
                    /* TScope: */ builder.ScopeType,
                    /* TContext: */ typeof(TContext),
                    /* TKey: */ typeof(TKey)));

            // Register the token store in the DI container.
            builder.Services.TryAddScoped(
                typeof(IOpenIddictTokenStore<>).MakeGenericType(builder.TokenType),
                typeof(OpenIddictTokenStore<,,,>).MakeGenericType(
                    /* TToken: */ builder.TokenType,
                    /* TAuthorization: */ builder.AuthorizationType,
                    /* TContext: */ typeof(TContext),
                    /* TKey: */ typeof(TKey)));

            return builder;
        }
Exemple #2
0
        /// <summary>
        /// Sets the issuer address, which is used as the base address
        /// for the endpoint URIs returned from the discovery endpoint.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="address">The issuer address.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder SetIssuer(
            [NotNull] this OpenIddictBuilder builder, [NotNull] Uri address)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            return(builder.Configure(options => options.Issuer = address));
        }
Exemple #3
0
        /// <summary>
        /// Registers a <see cref="X509Certificate2"/> retrieved from the X.509
        /// machine store and used to sign the JWT tokens issued by OpenIddict.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="thumbprint">The thumbprint of the certificate used to identify it in the X.509 store.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddSigningCertificate(
            [NotNull] this OpenIddictBuilder builder, [NotNull] string thumbprint)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (string.IsNullOrEmpty(thumbprint))
            {
                throw new ArgumentNullException(nameof(thumbprint));
            }

            return(builder.Configure(options => options.SigningCredentials.AddCertificate(thumbprint)));
        }
Exemple #4
0
        /// <summary>
        /// Registers a new ephemeral key used to sign the JWT tokens issued by OpenIddict: the key
        /// is discarded when the application shuts down and tokens signed using this key are
        /// automatically invalidated. This method should only be used during development.
        /// On production, using a X.509 certificate stored in the machine store is recommended.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="algorithm">The algorithm associated with the signing key.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddEphemeralSigningKey(
            [NotNull] this OpenIddictBuilder builder, [NotNull] string algorithm)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                throw new ArgumentException("The algorithm cannot be null or empty.", nameof(algorithm));
            }

            return(builder.Configure(options => options.SigningCredentials.AddEphemeralKey(algorithm)));
        }
Exemple #5
0
        /// <summary>
        /// Registers a <see cref="SecurityKey"/> used to sign the JWT tokens issued by OpenIddict.
        /// Note: using <see cref="RsaSecurityKey"/> asymmetric keys is recommended on production.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="key">The security key.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddSigningKey(
            [NotNull] this OpenIddictBuilder builder, [NotNull] SecurityKey key)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            return(builder.Configure(options => options.SigningCredentials.AddKey(key)));
        }
Exemple #6
0
        /// <summary>
        /// Configures OpenIddict to use a specific data protection provider
        /// instead of relying on the default instance provided by the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="provider">The data protection provider used to create token protectors.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder UseDataProtectionProvider(
            [NotNull] this OpenIddictBuilder builder, [NotNull] IDataProtectionProvider provider)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (provider == null)
            {
                throw new ArgumentNullException(nameof(provider));
            }

            return(builder.Configure(options => options.DataProtectionProvider = provider));
        }
Exemple #7
0
        /// <summary>
        /// Enables custom grant type support.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="type">The grant type associated with the flow.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AllowCustomFlow(
            [NotNull] this OpenIddictBuilder builder, [NotNull] string type)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (string.IsNullOrEmpty(type))
            {
                throw new ArgumentException("The grant type cannot be null or empty.", nameof(type));
            }

            return(builder.Configure(options => options.GrantTypes.Add(type)));
        }
Exemple #8
0
        /// <summary>
        /// Enables the userinfo endpoint.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="path">The relative path of the userinfo endpoint.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder EnableUserinfoEndpoint(
            [NotNull] this OpenIddictBuilder builder, PathString path)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (!path.HasValue)
            {
                throw new ArgumentException("The path cannot be empty.", nameof(path));
            }

            return(builder.Configure(options => options.UserinfoEndpointPath = path));
        }
Exemple #9
0
        /// <summary>
        /// Registers (and generates if necessary) a user-specific development
        /// certificate used to sign the JWT tokens issued by OpenIddict.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="subject">The subject name associated with the certificate.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddDevelopmentSigningCertificate(
            [NotNull] this OpenIddictBuilder builder, [NotNull] X500DistinguishedName subject)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (subject == null)
            {
                throw new ArgumentNullException(nameof(subject));
            }

            return(builder.Configure(options => options.SigningCredentials.AddDevelopmentCertificate(subject)));
        }
        /// <summary>
        /// Registers the OpenIddict core services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="configuration">The configuration delegate used to configure the core services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddCore(this OpenIddictBuilder builder, Action <OpenIddictCoreBuilder> configuration)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (configuration is null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            configuration(builder.AddCore());

            return(builder);
        }
        /// <summary>
        /// Registers the OpenIddict token server services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="configuration">The configuration delegate used to configure the server services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddServer(this OpenIddictBuilder builder, Action <OpenIddictServerBuilder> configuration)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            configuration(builder.AddServer());

            return(builder);
        }
Exemple #12
0
        /// <summary>
        /// Sets JWT as the default token format for access tokens.
        /// Note: this option cannot be used when using reference tokens.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder UseJsonWebTokens([NotNull] this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            return(builder.Configure(options =>
            {
                options.AccessTokenHandler = new JwtSecurityTokenHandler
                {
                    InboundClaimTypeMap = new Dictionary <string, string>(),
                    OutboundClaimTypeMap = new Dictionary <string, string>()
                };
            }));
        }
        /// <summary>
        /// Registers the OpenIddict token validation services in the DI container.
        /// Note: the validation handler only works with the default token format
        /// or reference tokens and cannot be used with JWT tokens. To validate
        /// JWT tokens, use the JWT bearer handler shipping with ASP.NET Core.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="configuration">The configuration delegate used to configure the validation services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddValidation(
            [NotNull] this OpenIddictBuilder builder,
            [NotNull] Action <OpenIddictValidationBuilder> configuration)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            configuration(builder.AddValidation());

            return(builder);
        }
Exemple #14
0
        /// <summary>
        /// Registers the OpenIddict token server services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
        public static OpenIddictServerBuilder AddServer([NotNull] this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddAuthentication();
            builder.Services.AddDistributedMemoryCache();
            builder.Services.AddLogging();
            builder.Services.AddMemoryCache();
            builder.Services.AddOptions();

            builder.Services.TryAddScoped <IOpenIddictServerEventDispatcher, OpenIddictServerEventDispatcher>();
            builder.Services.TryAddScoped <OpenIddictServerHandler>();
            builder.Services.TryAddScoped(provider =>
            {
                InvalidOperationException CreateException() => new InvalidOperationException(new StringBuilder()
                                                                                             .AppendLine("The core services must be registered when enabling the OpenIddict server handler.")
                                                                                             .Append("To register the OpenIddict core services, reference the 'OpenIddict.Core' package ")
                                                                                             .Append("and call 'services.AddOpenIddict().AddCore()' from 'ConfigureServices'.")
                                                                                             .ToString());

                return(new OpenIddictServerProvider(
                           provider.GetRequiredService <ILogger <OpenIddictServerProvider> >(),
                           provider.GetRequiredService <IOpenIddictServerEventDispatcher>(),
                           provider.GetService <IOpenIddictApplicationManager>() ?? throw CreateException(),
                           provider.GetService <IOpenIddictAuthorizationManager>() ?? throw CreateException(),
                           provider.GetService <IOpenIddictScopeManager>() ?? throw CreateException(),
                           provider.GetService <IOpenIddictTokenManager>() ?? throw CreateException()));
            });

            // Register the options initializers used by the OpenID Connect server handler and OpenIddict.
            // Note: TryAddEnumerable() is used here to ensure the initializers are only registered once.
            builder.Services.TryAddEnumerable(new[]
            {
                ServiceDescriptor.Singleton <IConfigureOptions <AuthenticationOptions>, OpenIddictServerConfiguration>(),
                ServiceDescriptor.Singleton <IPostConfigureOptions <AuthenticationOptions>, OpenIddictServerConfiguration>(),
                ServiceDescriptor.Singleton <IPostConfigureOptions <OpenIddictServerOptions>, OpenIddictServerConfiguration>(),
                ServiceDescriptor.Singleton <IPostConfigureOptions <OpenIddictServerOptions>, OpenIdConnectServerInitializer>()
            });

            return(new OpenIddictServerBuilder(builder.Services));
        }
        /// <summary>
        /// Registers the OpenIddict token server services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
        public static OpenIddictServerBuilder AddServer([NotNull] this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddLogging();
            builder.Services.AddOptions();

            builder.Services.TryAddScoped <IOpenIddictServerProvider, OpenIddictServerProvider>();

            // Register the built-in server event handlers used by the OpenIddict server components.
            // Note: the order used here is not important, as the actual order is set in the options.
            builder.Services.TryAdd(DefaultHandlers.Select(descriptor => descriptor.ServiceDescriptor));

            // Register the built-in filters used by the default OpenIddict server event handlers.
            builder.Services.TryAddSingleton <RequireAccessTokenIncluded>();
            builder.Services.TryAddSingleton <RequireAuthorizationCodeIncluded>();
            builder.Services.TryAddSingleton <RequireAuthorizationStorageEnabled>();
            builder.Services.TryAddSingleton <RequireClientIdParameter>();
            builder.Services.TryAddSingleton <RequireDegradedModeDisabled>();
            builder.Services.TryAddSingleton <RequireDeviceCodeIncluded>();
            builder.Services.TryAddSingleton <RequireEndpointPermissionsEnabled>();
            builder.Services.TryAddSingleton <RequireGrantTypePermissionsEnabled>();
            builder.Services.TryAddSingleton <RequireIdentityTokenIncluded>();
            builder.Services.TryAddSingleton <RequirePostLogoutRedirectUriParameter>();
            builder.Services.TryAddSingleton <RequireReferenceAccessTokensEnabled>();
            builder.Services.TryAddSingleton <RequireRefreshTokenIncluded>();
            builder.Services.TryAddSingleton <RequireRollingTokensDisabled>();
            builder.Services.TryAddSingleton <RequireRollingTokensEnabled>();
            builder.Services.TryAddSingleton <RequireSlidingExpirationEnabled>();
            builder.Services.TryAddSingleton <RequireScopePermissionsEnabled>();
            builder.Services.TryAddSingleton <RequireScopeValidationEnabled>();
            builder.Services.TryAddSingleton <RequireTokenStorageEnabled>();
            builder.Services.TryAddSingleton <RequireUserCodeIncluded>();

            // Note: TryAddEnumerable() is used here to ensure the initializer is registered only once.
            builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton <
                                                  IPostConfigureOptions <OpenIddictServerOptions>, OpenIddictServerConfiguration>());

            return(new OpenIddictServerBuilder(builder.Services));
        }
        /// <summary>
        /// Registers the OpenIddict token validation services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
        public static OpenIddictValidationBuilder AddValidation(this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddLogging();
            builder.Services.AddOptions();

            builder.Services.TryAddSingleton <OpenIddictValidationService>();
            builder.Services.TryAddScoped <IOpenIddictValidationDispatcher, OpenIddictValidationDispatcher>();
            builder.Services.TryAddScoped <IOpenIddictValidationFactory, OpenIddictValidationFactory>();

            // Register the built-in validation event handlers used by the OpenIddict validation components.
            // Note: the order used here is not important, as the actual order is set in the options.
            builder.Services.TryAdd(DefaultHandlers.Select(descriptor => descriptor.ServiceDescriptor));

            // Register the built-in filters used by the default OpenIddict validation event handlers.
            builder.Services.TryAddSingleton <RequireAuthorizationEntryValidationEnabled>();
            builder.Services.TryAddSingleton <RequireLocalValidation>();
            builder.Services.TryAddSingleton <RequireTokenEntryValidationEnabled>();
            builder.Services.TryAddSingleton <RequireIntrospectionValidation>();

            builder.Services.TryAddSingleton <IStringLocalizer <OpenIddictResources> >(provider =>
            {
                // Note: the string localizer factory is deliberately not resolved from
                // the DI container to ensure the built-in .resx files are always used
                // even if the factory was replaced by a different implementation in DI.
                var factory = new ResourceManagerStringLocalizerFactory(
                    localizationOptions: Options.Create(new LocalizationOptions()),
                    loggerFactory: NullLoggerFactory.Instance);

                return(new StringLocalizer <OpenIddictResources>(factory));
            });

            // Note: TryAddEnumerable() is used here to ensure the initializer is registered only once.
            builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton <
                                                  IPostConfigureOptions <OpenIddictValidationOptions>, OpenIddictValidationConfiguration>());

            return(new OpenIddictValidationBuilder(builder.Services));
        }
Exemple #17
0
        /// <summary>
        /// Registers the specified scopes as supported scopes so
        /// they can be returned as part of the discovery document.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="scopes">The supported scopes.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder RegisterScopes(
            [NotNull] this OpenIddictBuilder builder, [NotNull] params string[] scopes)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (scopes == null)
            {
                throw new ArgumentNullException(nameof(scopes));
            }

            if (scopes.Any(scope => string.IsNullOrEmpty(scope)))
            {
                throw new ArgumentException("Scopes cannot be null or empty.", nameof(scopes));
            }

            return(builder.Configure(options => options.Scopes.UnionWith(scopes)));
        }
Exemple #18
0
        /// <summary>
        /// Registers the specified claims as supported claims so
        /// they can be returned as part of the discovery document.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="claims">The supported claims.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder RegisterClaims(
            [NotNull] this OpenIddictBuilder builder, [NotNull] params string[] claims)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (claims == null)
            {
                throw new ArgumentNullException(nameof(claims));
            }

            if (claims.Any(claim => string.IsNullOrEmpty(claim)))
            {
                throw new ArgumentException("Claims cannot be null or empty.", nameof(claims));
            }

            return(builder.Configure(options => options.Claims.UnionWith(claims)));
        }
Exemple #19
0
        /// <summary>
        /// Registers the OpenIddict token validation services in the DI container.
        /// Note: the validation handler only works with the default token format
        /// or reference tokens and cannot be used with JWT tokens. To validate
        /// JWT tokens, use the JWT bearer handler shipping with ASP.NET Core.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
        public static OpenIddictValidationBuilder AddValidation([NotNull] this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddAuthentication();
            builder.Services.AddLogging();
            builder.Services.AddOptions();

            builder.Services.TryAddScoped <IOpenIddictValidationEventService, OpenIddictValidationEventService>();
            builder.Services.TryAddScoped <OpenIddictValidationHandler>();
            builder.Services.TryAddScoped <OpenIddictValidationProvider>();

            // Note: TryAddEnumerable() is used here to ensure the initializer is only registered once.
            builder.Services.TryAddEnumerable(new[]
            {
                ServiceDescriptor.Singleton <IPostConfigureOptions <OpenIddictValidationOptions>, OpenIddictValidationInitializer>(),
                ServiceDescriptor.Singleton <IPostConfigureOptions <OpenIddictValidationOptions>, OAuthValidationInitializer>()
            });

            // Register the OpenIddict validation handler in the authentication options,
            // so it can be discovered by the default authentication handler provider.
            builder.Services.Configure <AuthenticationOptions>(options =>
            {
                // Note: this method is guaranteed to be idempotent. To prevent multiple schemes from being
                // registered (which would result in an exception being thrown), a manual check is made here.
                if (options.SchemeMap.ContainsKey(OpenIddictValidationDefaults.AuthenticationScheme))
                {
                    return;
                }

                options.AddScheme(OpenIddictValidationDefaults.AuthenticationScheme, scheme =>
                {
                    scheme.HandlerType = typeof(OpenIddictValidationHandler);
                });
            });

            return(new OpenIddictValidationBuilder(builder.Services));
        }
Exemple #20
0
        /// <summary>
        /// Registers a <see cref="X509Certificate2"/> that is used to sign the JWT tokens issued by OpenIddict.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="certificate">The certificate used to sign the security tokens issued by the server.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddSigningCertificate(
            [NotNull] this OpenIddictBuilder builder,
            [NotNull] X509Certificate2 certificate)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            if (!certificate.HasPrivateKey)
            {
                throw new InvalidOperationException("The certificate doesn't contain the required private key.");
            }

            return(builder.Configure(options => options.SigningCredentials.AddCertificate(certificate)));
        }
Exemple #21
0
        /// <summary>
        /// Registers a <see cref="X509Certificate2"/> extracted from a
        /// stream and used to sign the JWT tokens issued by OpenIddict.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <param name="stream">The stream containing the certificate.</param>
        /// <param name="password">The password used to open the certificate.</param>
        /// <param name="flags">
        /// An enumeration of flags indicating how and where
        /// to store the private key of the certificate.
        /// </param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddSigningCertificate(
            [NotNull] this OpenIddictBuilder builder, [NotNull] Stream stream,
            [NotNull] string password, X509KeyStorageFlags flags)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException(nameof(password));
            }

            return(builder.Configure(options => options.SigningCredentials.AddCertificate(stream, password, flags)));
        }
        /// <summary>
        /// Registers the ASP.NET Core MVC model binders used by OpenIddict.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddMvcBinders([NotNull] this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.Configure <MvcOptions>(options => {
                // Skip the binder registration if it was already added to the providers collection.
                for (var index = 0; index < options.ModelBinderProviders.Count; index++)
                {
                    var provider = options.ModelBinderProviders[index];
                    if (provider is OpenIddictModelBinder)
                    {
                        return;
                    }
                }

                options.ModelBinderProviders.Insert(0, new OpenIddictModelBinder());
            });

            return(builder);
        }
Exemple #23
0
        /// <summary>
        /// Registers the OpenIddict core services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictCoreBuilder AddCore([NotNull] this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddDistributedMemoryCache();
            builder.Services.AddMemoryCache();
            builder.Services.AddOptions();

            builder.Services.TryAddScoped(typeof(OpenIddictApplicationManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictAuthorizationManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictScopeManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictTokenManager <>));

            builder.Services.TryAddScoped <IOpenIddictApplicationStoreResolver, OpenIddictApplicationStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictAuthorizationStoreResolver, OpenIddictAuthorizationStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictScopeStoreResolver, OpenIddictScopeStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictTokenStoreResolver, OpenIddictTokenStoreResolver>();

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultApplicationType == null)
                {
                    throw new InvalidOperationException(new StringBuilder()
                                                        .AppendLine("The default application type must be configured for the non-generic services to work correctly.")
                                                        .Append("To configure the entities, use either 'services.AddOpenIddict().AddCore().UseDefaultModels()' ")
                                                        .Append("or 'services.AddOpenIddict().AddCore().UseCustomModels()'.")
                                                        .ToString());
                }

                return((IOpenIddictApplicationManager)provider.GetRequiredService(
                           typeof(OpenIddictApplicationManager <>).MakeGenericType(options.DefaultApplicationType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultAuthorizationType == null)
                {
                    throw new InvalidOperationException(new StringBuilder()
                                                        .AppendLine("The default authorization type must be configured for the non-generic services to work correctly.")
                                                        .Append("To configure the entities, use either 'services.AddOpenIddict().AddCore().UseDefaultModels()' ")
                                                        .Append("or 'services.AddOpenIddict().AddCore().UseCustomModels()'.")
                                                        .ToString());
                }

                return((IOpenIddictAuthorizationManager)provider.GetRequiredService(
                           typeof(OpenIddictAuthorizationManager <>).MakeGenericType(options.DefaultAuthorizationType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultScopeType == null)
                {
                    throw new InvalidOperationException(new StringBuilder()
                                                        .AppendLine("The default scope type must be configured for the non-generic services to work correctly.")
                                                        .Append("To configure the entities, use either 'services.AddOpenIddict().AddCore().UseDefaultModels()' ")
                                                        .Append("or 'services.AddOpenIddict().AddCore().UseCustomModels()'.")
                                                        .ToString());
                }

                return((IOpenIddictScopeManager)provider.GetRequiredService(
                           typeof(OpenIddictScopeManager <>).MakeGenericType(options.DefaultScopeType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultTokenType == null)
                {
                    throw new InvalidOperationException(new StringBuilder()
                                                        .AppendLine("The default token type must be configured for the non-generic services to work correctly.")
                                                        .Append("To configure the entities, use either 'services.AddOpenIddict().AddCore().UseDefaultModels()' ")
                                                        .Append("or 'services.AddOpenIddict().AddCore().UseCustomModels()'.")
                                                        .ToString());
                }

                return((IOpenIddictTokenManager)provider.GetRequiredService(
                           typeof(OpenIddictTokenManager <>).MakeGenericType(options.DefaultTokenType)));
            });

            return(new OpenIddictCoreBuilder(builder.Services));
        }
Exemple #24
0
        /// <summary>
        /// Registers the OpenIddict token server services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
        public static OpenIddictServerBuilder AddServer([NotNull] this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddAuthentication();
            builder.Services.AddDistributedMemoryCache();
            builder.Services.AddLogging();
            builder.Services.AddMemoryCache();
            builder.Services.AddOptions();

            builder.Services.TryAddScoped <OpenIddictServerEventService>();
            builder.Services.TryAddScoped <OpenIddictServerHandler>();
            builder.Services.TryAddScoped(provider =>
            {
                InvalidOperationException CreateException() => new InvalidOperationException(new StringBuilder()
                                                                                             .AppendLine("The core services must be registered when enabling the OpenIddict server handler.")
                                                                                             .Append("To register the OpenIddict core services, reference the 'OpenIddict.Core' package ")
                                                                                             .Append("and call 'services.AddOpenIddict().AddCore()' from 'ConfigureServices'.")
                                                                                             .ToString());

                return(new OpenIddictServerProvider(
                           provider.GetRequiredService <ILogger <OpenIddictServerProvider> >(),
                           provider.GetRequiredService <OpenIddictServerEventService>(),
                           provider.GetService <IOpenIddictApplicationManager>() ?? throw CreateException(),
                           provider.GetService <IOpenIddictAuthorizationManager>() ?? throw CreateException(),
                           provider.GetService <IOpenIddictScopeManager>() ?? throw CreateException(),
                           provider.GetService <IOpenIddictTokenManager>() ?? throw CreateException()));
            });

            // Register the options initializers used by the OpenID Connect server handler and OpenIddict.
            // Note: TryAddEnumerable() is used here to ensure the initializers are only registered once.
            builder.Services.TryAddEnumerable(new[]
            {
                ServiceDescriptor.Singleton <IPostConfigureOptions <OpenIddictServerOptions>, OpenIddictServerInitializer>(),
                ServiceDescriptor.Singleton <IPostConfigureOptions <OpenIddictServerOptions>, OpenIdConnectServerInitializer>()
            });

            // Register the OpenID Connect server handler in the authentication options,
            // so it can be discovered by the default authentication handler provider.
            builder.Services.Configure <AuthenticationOptions>(options =>
            {
                // Note: this method is guaranteed to be idempotent. To prevent multiple schemes from being
                // registered (which would result in an exception being thrown), a manual check is made here.
                if (options.SchemeMap.TryGetValue(OpenIddictServerDefaults.AuthenticationScheme, out var handler))
                {
                    // If the handler type doesn't correspond to the OpenIddict handler, throw an exception.
                    if (handler.HandlerType != typeof(OpenIddictServerHandler))
                    {
                        throw new InvalidOperationException(new StringBuilder()
                                                            .AppendLine("The OpenIddict server handler cannot be registered as an authentication scheme.")
                                                            .AppendLine("This may indicate that an instance of the OpenID Connect server was registered.")
                                                            .Append("Make sure that 'services.AddAuthentication().AddOpenIdConnectServer()' is not used.")
                                                            .ToString());
                    }

                    return;
                }

                options.AddScheme(OpenIddictServerDefaults.AuthenticationScheme, scheme =>
                {
                    scheme.HandlerType = typeof(OpenIddictServerHandler);
                });
            });

            return(new OpenIddictServerBuilder(builder.Services));
        }
        /// <summary>
        /// Registers the OpenIddict core services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictCoreBuilder AddCore([NotNull] this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddLogging();
            builder.Services.AddOptions();

            builder.Services.TryAddScoped(typeof(OpenIddictApplicationManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictAuthorizationManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictScopeManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictTokenManager <>));

            builder.Services.TryAddScoped <IOpenIddictApplicationStoreResolver, OpenIddictApplicationStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictAuthorizationStoreResolver, OpenIddictAuthorizationStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictScopeStoreResolver, OpenIddictScopeStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictTokenStoreResolver, OpenIddictTokenStoreResolver>();

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultApplicationType == null)
                {
                    throw new InvalidOperationException(new StringBuilder()
                                                        .Append("No default application entity type was configured in the OpenIddict core options, ")
                                                        .AppendLine("which generally indicates that no application store was registered in the DI container.")
                                                        .Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
                                                        .Append("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
                                                        .ToString());
                }

                return((IOpenIddictApplicationManager)provider.GetRequiredService(
                           typeof(OpenIddictApplicationManager <>).MakeGenericType(options.DefaultApplicationType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultAuthorizationType == null)
                {
                    throw new InvalidOperationException(new StringBuilder()
                                                        .Append("No default authorization entity type was configured in the OpenIddict core options, ")
                                                        .AppendLine("which generally indicates that no authorization store was registered in the DI container.")
                                                        .Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
                                                        .Append("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
                                                        .ToString());
                }

                return((IOpenIddictAuthorizationManager)provider.GetRequiredService(
                           typeof(OpenIddictAuthorizationManager <>).MakeGenericType(options.DefaultAuthorizationType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultScopeType == null)
                {
                    throw new InvalidOperationException(new StringBuilder()
                                                        .Append("No default scope entity type was configured in the OpenIddict core options, ")
                                                        .AppendLine("which generally indicates that no scope store was registered in the DI container.")
                                                        .Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
                                                        .Append("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
                                                        .ToString());
                }

                return((IOpenIddictScopeManager)provider.GetRequiredService(
                           typeof(OpenIddictScopeManager <>).MakeGenericType(options.DefaultScopeType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultTokenType == null)
                {
                    throw new InvalidOperationException(new StringBuilder()
                                                        .Append("No default token entity type was configured in the OpenIddict core options, ")
                                                        .AppendLine("which generally indicates that no token store was registered in the DI container.")
                                                        .Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
                                                        .Append("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
                                                        .ToString());
                }

                return((IOpenIddictTokenManager)provider.GetRequiredService(
                           typeof(OpenIddictTokenManager <>).MakeGenericType(options.DefaultTokenType)));
            });

            return(new OpenIddictCoreBuilder(builder.Services));
        }
 /// <summary>
 /// Registers the Entity Framework stores. Note: when using the built-in Entity Framework stores,
 /// the entities MUST be derived from the models contained in the OpenIddict.Models package.
 /// </summary>
 /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
 /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
 public static OpenIddictBuilder AddEntityFrameworkCoreStores<TContext>([NotNull] this OpenIddictBuilder builder)
     where TContext : DbContext {
     return builder.AddEntityFrameworkCoreStores<TContext, string>();
 }
        /// <summary>
        /// Registers the OpenIddict core services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictCoreBuilder AddCore(this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddLocalization();
            builder.Services.AddLogging();
            builder.Services.AddMemoryCache();
            builder.Services.AddOptions();

            builder.Services.TryAddScoped(typeof(OpenIddictApplicationManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictAuthorizationManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictScopeManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictTokenManager <>));

            builder.Services.TryAddScoped(typeof(IOpenIddictApplicationCache <>), typeof(OpenIddictApplicationCache <>));
            builder.Services.TryAddScoped(typeof(IOpenIddictAuthorizationCache <>), typeof(OpenIddictAuthorizationCache <>));
            builder.Services.TryAddScoped(typeof(IOpenIddictScopeCache <>), typeof(OpenIddictScopeCache <>));
            builder.Services.TryAddScoped(typeof(IOpenIddictTokenCache <>), typeof(OpenIddictTokenCache <>));

            builder.Services.TryAddScoped <IOpenIddictApplicationStoreResolver, OpenIddictApplicationStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictAuthorizationStoreResolver, OpenIddictAuthorizationStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictScopeStoreResolver, OpenIddictScopeStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictTokenStoreResolver, OpenIddictTokenStoreResolver>();

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultApplicationType == null)
                {
                    throw new InvalidOperationException(SR.GetResourceString(SR.ID1272));
                }

                return((IOpenIddictApplicationManager)provider.GetRequiredService(
                           typeof(OpenIddictApplicationManager <>).MakeGenericType(options.DefaultApplicationType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultAuthorizationType == null)
                {
                    throw new InvalidOperationException(SR.GetResourceString(SR.ID1273));
                }

                return((IOpenIddictAuthorizationManager)provider.GetRequiredService(
                           typeof(OpenIddictAuthorizationManager <>).MakeGenericType(options.DefaultAuthorizationType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultScopeType == null)
                {
                    throw new InvalidOperationException(SR.GetResourceString(SR.ID1274));
                }

                return((IOpenIddictScopeManager)provider.GetRequiredService(
                           typeof(OpenIddictScopeManager <>).MakeGenericType(options.DefaultScopeType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultTokenType == null)
                {
                    throw new InvalidOperationException(SR.GetResourceString(SR.ID1275));
                }

                return((IOpenIddictTokenManager)provider.GetRequiredService(
                           typeof(OpenIddictTokenManager <>).MakeGenericType(options.DefaultTokenType)));
            });

            builder.Services.TryAddSingleton <IStringLocalizer <OpenIddictResources> >(provider =>
            {
                // Note: the string localizer factory is deliberately not resolved from
                // the DI container to ensure the built-in .resx files are always used
                // even if the factory was replaced by a different implementation in DI.
                var factory = new ResourceManagerStringLocalizerFactory(
                    localizationOptions: Options.Create(new LocalizationOptions()),
                    loggerFactory: NullLoggerFactory.Instance);

                return(new StringLocalizer <OpenIddictResources>(factory));
            });

            return(new OpenIddictCoreBuilder(builder.Services));
        }
        /// <summary>
        /// Registers the OpenIddict token server services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
        public static OpenIddictServerBuilder AddServer(this OpenIddictBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddLocalization();
            builder.Services.AddLogging();
            builder.Services.AddOptions();

            builder.Services.TryAddScoped <IOpenIddictServerDispatcher, OpenIddictServerDispatcher>();
            builder.Services.TryAddScoped <IOpenIddictServerFactory, OpenIddictServerFactory>();

            // Register the built-in server event handlers used by the OpenIddict server components.
            // Note: the order used here is not important, as the actual order is set in the options.
            builder.Services.TryAdd(DefaultHandlers.Select(descriptor => descriptor.ServiceDescriptor));

            // Register the built-in filters used by the default OpenIddict server event handlers.
            builder.Services.TryAddSingleton <RequireAccessTokenIncluded>();
            builder.Services.TryAddSingleton <RequireAuthorizationCodeIncluded>();
            builder.Services.TryAddSingleton <RequireAuthorizationStorageEnabled>();
            builder.Services.TryAddSingleton <RequireAuthorizationRequest>();
            builder.Services.TryAddSingleton <RequireClientIdParameter>();
            builder.Services.TryAddSingleton <RequireConfigurationRequest>();
            builder.Services.TryAddSingleton <RequireCryptographyRequest>();
            builder.Services.TryAddSingleton <RequireDegradedModeDisabled>();
            builder.Services.TryAddSingleton <RequireDeviceCodeIncluded>();
            builder.Services.TryAddSingleton <RequireDeviceRequest>();
            builder.Services.TryAddSingleton <RequireEndpointPermissionsEnabled>();
            builder.Services.TryAddSingleton <RequireGrantTypePermissionsEnabled>();
            builder.Services.TryAddSingleton <RequireIdentityTokenIncluded>();
            builder.Services.TryAddSingleton <RequireIntrospectionRequest>();
            builder.Services.TryAddSingleton <RequireLogoutRequest>();
            builder.Services.TryAddSingleton <RequirePostLogoutRedirectUriParameter>();
            builder.Services.TryAddSingleton <RequireReferenceAccessTokensEnabled>();
            builder.Services.TryAddSingleton <RequireReferenceRefreshTokensEnabled>();
            builder.Services.TryAddSingleton <RequireRefreshTokenIncluded>();
            builder.Services.TryAddSingleton <RequireRevocationRequest>();
            builder.Services.TryAddSingleton <RequireRollingTokensDisabled>();
            builder.Services.TryAddSingleton <RequireRollingRefreshTokensEnabled>();
            builder.Services.TryAddSingleton <RequireSlidingRefreshTokenExpirationEnabled>();
            builder.Services.TryAddSingleton <RequireScopePermissionsEnabled>();
            builder.Services.TryAddSingleton <RequireScopeValidationEnabled>();
            builder.Services.TryAddSingleton <RequireTokenStorageEnabled>();
            builder.Services.TryAddSingleton <RequireTokenRequest>();
            builder.Services.TryAddSingleton <RequireUserCodeIncluded>();
            builder.Services.TryAddSingleton <RequireUserinfoRequest>();
            builder.Services.TryAddSingleton <RequireVerificationRequest>();

            builder.Services.TryAddSingleton <IStringLocalizer <OpenIddictResources> >(provider =>
            {
                // Note: the string localizer factory is deliberately not resolved from
                // the DI container to ensure the built-in .resx files are always used
                // even if the factory was replaced by a different implementation in DI.
                var factory = new ResourceManagerStringLocalizerFactory(
                    localizationOptions: Options.Create(new LocalizationOptions()),
                    loggerFactory: NullLoggerFactory.Instance);

                return(new StringLocalizer <OpenIddictResources>(factory));
            });

            // Note: TryAddEnumerable() is used here to ensure the initializer is registered only once.
            builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton <
                                                  IPostConfigureOptions <OpenIddictServerOptions>, OpenIddictServerConfiguration>());

            return(new OpenIddictServerBuilder(builder.Services));
        }
        /// <summary>
        /// Registers the Entity Framework 6.x stores. Note: when using the Entity Framework stores,
        /// the application <see cref="DbContext"/> MUST be manually registered in the DI container and
        /// the entities MUST be derived from the models contained in the OpenIddict.Models package.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictBuilder AddEntityFrameworkStores <TContext>([NotNull] this OpenIddictBuilder builder)
            where TContext : DbContext
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            Debug.Assert(builder.ApplicationType != null &&
                         builder.AuthorizationType != null &&
                         builder.ScopeType != null &&
                         builder.TokenType != null, "The entity types exposed by OpenIddictBuilder shouldn't be null.");

            var application = FindGenericBaseType(builder.ApplicationType, typeof(OpenIddictApplication <, ,>));

            if (application == null)
            {
                throw new InvalidOperationException("The Entity Framework stores can only be used " +
                                                    "with the built-in OpenIddictApplication entity.");
            }

            var authorization = FindGenericBaseType(builder.AuthorizationType, typeof(OpenIddictAuthorization <, ,>));

            if (authorization == null)
            {
                throw new InvalidOperationException("The Entity Framework stores can only be used " +
                                                    "with the built-in OpenIddictAuthorization entity.");
            }

            var scope = FindGenericBaseType(builder.ScopeType, typeof(OpenIddictScope <>));

            if (scope == null)
            {
                throw new InvalidOperationException("The Entity Framework stores can only be used " +
                                                    "with the built-in OpenIddictScope entity.");
            }

            var token = FindGenericBaseType(builder.TokenType, typeof(OpenIddictToken <, ,>));

            if (token == null)
            {
                throw new InvalidOperationException("The Entity Framework stores can only be used " +
                                                    "with the built-in OpenIddictToken entity.");
            }

            var converter = TypeDescriptor.GetConverter(application.GenericTypeArguments[0]);

            if (converter == null || !converter.CanConvertFrom(typeof(string)) ||
                !converter.CanConvertTo(typeof(string)))
            {
                throw new InvalidOperationException("The specified entity key type is not supported.");
            }

            // Register the application store in the DI container.
            builder.Services.TryAddScoped(
                typeof(IOpenIddictApplicationStore <>).MakeGenericType(builder.ApplicationType),
                typeof(OpenIddictApplicationStore <, , , ,>).MakeGenericType(
                    /* TApplication: */ builder.ApplicationType,
                    /* TAuthorization: */ builder.AuthorizationType,
                    /* TToken: */ builder.TokenType,
                    /* TContext: */ typeof(TContext),
                    /* TKey: */ application.GenericTypeArguments[0]));

            // Register the authorization store in the DI container.
            builder.Services.TryAddScoped(
                typeof(IOpenIddictAuthorizationStore <>).MakeGenericType(builder.AuthorizationType),
                typeof(OpenIddictAuthorizationStore <, , , ,>).MakeGenericType(
                    /* TAuthorization: */ builder.AuthorizationType,
                    /* TApplication: */ builder.ApplicationType,
                    /* TToken: */ builder.TokenType,
                    /* TContext: */ typeof(TContext),
                    /* TKey: */ authorization.GenericTypeArguments[0]));

            // Register the scope store in the DI container.
            builder.Services.TryAddScoped(
                typeof(IOpenIddictScopeStore <>).MakeGenericType(builder.ScopeType),
                typeof(OpenIddictScopeStore <, ,>).MakeGenericType(
                    /* TScope: */ builder.ScopeType,
                    /* TContext: */ typeof(TContext),
                    /* TKey: */ scope.GenericTypeArguments[0]));

            // Register the token store in the DI container.
            builder.Services.TryAddScoped(
                typeof(IOpenIddictTokenStore <>).MakeGenericType(builder.TokenType),
                typeof(OpenIddictTokenStore <, , , ,>).MakeGenericType(
                    /* TToken: */ builder.TokenType,
                    /* TApplication: */ builder.ApplicationType,
                    /* TAuthorization: */ builder.AuthorizationType,
                    /* TContext: */ typeof(TContext),
                    /* TKey: */ token.GenericTypeArguments[0]));

            return(builder);
        }
Exemple #30
0
        /// <summary>
        /// Registers the OpenIddict core services in the DI container.
        /// </summary>
        /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
        /// <remarks>This extension can be safely called multiple times.</remarks>
        /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
        public static OpenIddictCoreBuilder AddCore(this OpenIddictBuilder builder)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddLogging();
            builder.Services.AddMemoryCache();
            builder.Services.AddOptions();

            builder.Services.TryAddScoped(typeof(OpenIddictApplicationManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictAuthorizationManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictScopeManager <>));
            builder.Services.TryAddScoped(typeof(OpenIddictTokenManager <>));

            builder.Services.TryAddScoped(typeof(IOpenIddictApplicationCache <>), typeof(OpenIddictApplicationCache <>));
            builder.Services.TryAddScoped(typeof(IOpenIddictAuthorizationCache <>), typeof(OpenIddictAuthorizationCache <>));
            builder.Services.TryAddScoped(typeof(IOpenIddictScopeCache <>), typeof(OpenIddictScopeCache <>));
            builder.Services.TryAddScoped(typeof(IOpenIddictTokenCache <>), typeof(OpenIddictTokenCache <>));

            builder.Services.TryAddScoped <IOpenIddictApplicationStoreResolver, OpenIddictApplicationStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictAuthorizationStoreResolver, OpenIddictAuthorizationStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictScopeStoreResolver, OpenIddictScopeStoreResolver>();
            builder.Services.TryAddScoped <IOpenIddictTokenStoreResolver, OpenIddictTokenStoreResolver>();

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultApplicationType is null)
                {
                    throw new InvalidOperationException(SR.GetResourceString(SR.ID0273));
                }

                return((IOpenIddictApplicationManager)provider.GetRequiredService(
                           typeof(OpenIddictApplicationManager <>).MakeGenericType(options.DefaultApplicationType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultAuthorizationType is null)
                {
                    throw new InvalidOperationException(SR.GetResourceString(SR.ID0274));
                }

                return((IOpenIddictAuthorizationManager)provider.GetRequiredService(
                           typeof(OpenIddictAuthorizationManager <>).MakeGenericType(options.DefaultAuthorizationType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultScopeType is null)
                {
                    throw new InvalidOperationException(SR.GetResourceString(SR.ID0275));
                }

                return((IOpenIddictScopeManager)provider.GetRequiredService(
                           typeof(OpenIddictScopeManager <>).MakeGenericType(options.DefaultScopeType)));
            });

            builder.Services.TryAddScoped(provider =>
            {
                var options = provider.GetRequiredService <IOptionsMonitor <OpenIddictCoreOptions> >().CurrentValue;
                if (options.DefaultTokenType is null)
                {
                    throw new InvalidOperationException(SR.GetResourceString(SR.ID0276));
                }

                return((IOpenIddictTokenManager)provider.GetRequiredService(
                           typeof(OpenIddictTokenManager <>).MakeGenericType(options.DefaultTokenType)));
            });

            return(new OpenIddictCoreBuilder(builder.Services));
        }