private static Type ResolveKeyType([NotNull] OpenIddictConfiguration configuration)
        {
            TypeInfo type;

            for (type = configuration.UserType.GetTypeInfo(); type != null; type = type.BaseType?.GetTypeInfo())
            {
                if (!type.IsGenericType)
                {
                    continue;
                }

                var definition = type.GetGenericTypeDefinition();
                if (definition == null)
                {
                    continue;
                }

                if (definition != typeof(IdentityUser <>))
                {
                    continue;
                }

                return(type.AsType().GetGenericArguments().Single());
            }

            throw new InvalidOperationException(
                      "The type of the key identifier used by the user " +
                      $"entity '{configuration.UserType}' cannot be automatically inferred.");
        }
Exemple #2
0
 public OpenIddictPart(OpenIddictConfiguration configuration)
 {
     Types = new[] {
         typeof(OpenIddictController <,>)
         .MakeGenericType(configuration.UserType,
                          configuration.ApplicationType)
         .GetTypeInfo()
     };
 }
        public static IdentityBuilder AddOpenIddictCore <TApplication>(
            [NotNull] this IdentityBuilder builder,
            [NotNull] Action <OpenIddictConfiguration> configuration)
            where TApplication : class
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            builder.Services.AddAuthentication();
            builder.Services.AddDistributedMemoryCache();

            builder.Services.TryAddSingleton(
                typeof(IOpenIdConnectServerProvider),
                typeof(OpenIddictProvider <,>).MakeGenericType(
                    builder.UserType, typeof(TApplication)));

            builder.Services.TryAddScoped(
                typeof(OpenIddictManager <,>).MakeGenericType(
                    builder.UserType, typeof(TApplication)));

            builder.Services.TryAddTransient(
                typeof(OpenIddictServices <,>).MakeGenericType(
                    builder.UserType, typeof(TApplication)));

            var instance = new OpenIddictConfiguration(builder.Services)
            {
                ApplicationType = typeof(TApplication),
                RoleType        = builder.RoleType,
                UserType        = builder.UserType
            };

            builder.Services.TryAddSingleton(instance);

            configuration(instance);

            return(builder);
        }
        public static OpenIddictConfiguration UseStore <TStore>([NotNull] this OpenIddictConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var contract = typeof(IOpenIddictStore <,>).MakeGenericType(configuration.UserType,
                                                                        configuration.ApplicationType);

            if (!contract.IsAssignableFrom(typeof(TStore)))
            {
                throw new InvalidOperationException("Custom stores must implement IOpenIddictStore.");
            }

            configuration.Services.Replace(ServiceDescriptor.Scoped(contract, typeof(TStore)));

            return(configuration);
        }
        public static OpenIddictConfiguration UseManager <TManager>([NotNull] this OpenIddictConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var contract = typeof(OpenIddictManager <,>).MakeGenericType(configuration.UserType,
                                                                         configuration.ApplicationType);

            if (!contract.IsAssignableFrom(typeof(TManager)))
            {
                throw new InvalidOperationException("Custom managers must be derived from OpenIddictManager.");
            }

            configuration.Services.Replace(ServiceDescriptor.Scoped(contract, typeof(TManager)));

            return(configuration);
        }
        private static Type ResolveContextType([NotNull] OpenIddictConfiguration configuration)
        {
            var service = (from registration in configuration.Services
                           where registration.ServiceType.IsConstructedGenericType
                           let definition = registration.ServiceType.GetGenericTypeDefinition()
                                            where definition == typeof(IUserStore <>)
                                            select registration.ImplementationType).FirstOrDefault();

            if (service == null)
            {
                throw new InvalidOperationException(
                          "The type of the database context cannot be automatically inferred. " +
                          "Make sure 'AddOpenIddict()' is the last chained call when configuring the services.");
            }

            TypeInfo type;

            for (type = service.GetTypeInfo(); type != null; type = type.BaseType?.GetTypeInfo())
            {
                if (!type.IsGenericType)
                {
                    continue;
                }

                var definition = type.GetGenericTypeDefinition();
                if (definition == null)
                {
                    continue;
                }

                if (definition != typeof(UserStore <, , ,>))
                {
                    continue;
                }

                return((from argument in type.AsType().GetGenericArguments()
                        where typeof(DbContext).IsAssignableFrom(argument)
                        select argument).Single());
            }

            throw new InvalidOperationException("The type of the database context cannot be automatically inferred.");
        }
                static TokenValidationParameters GetServerTokenValidationParameters(
                    OpenIddictClientRegistration registration, OpenIddictConfiguration configuration)
                {
                    var parameters = registration !.TokenValidationParameters.Clone();

                    parameters.ValidIssuers ??= configuration.Issuer switch
                    {
                        null => null,

                        // If the issuer URI doesn't contain any path/query/fragment, allow both http://www.fabrikam.com
                        // and http://www.fabrikam.com/ (the recommended URI representation) to be considered valid.
                        // See https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.3 for more information.
                        { AbsolutePath : "/", Query.Length : 0, Fragment.Length : 0 } issuer => new[]
                        {
                            issuer.AbsoluteUri, // Uri.AbsoluteUri is normalized and always contains a trailing slash.
                            issuer.AbsoluteUri.Substring(0, issuer.AbsoluteUri.Length - 1)
                        },

                        Uri issuer => new[] { issuer.AbsoluteUri }
                    };

                    parameters.ValidateIssuer = parameters.ValidIssuers is not null;

                    // Combine the signing keys registered statically in the token validation parameters
                    // with the signing keys resolved from the OpenID Connect server configuration.
                    parameters.IssuerSigningKeys =
                        parameters.IssuerSigningKeys?.Concat(configuration.SigningKeys) ?? configuration.SigningKeys;

                    // For maximum compatibility, all "typ" values are accepted for all types of JSON Web Tokens,
                    // which typically includes identity tokens but can also include access tokens, authorization
                    // codes or refresh tokens for non-standard implementations that need to read these tokens.
                    //
                    // To prevent token mix-up/confused deputy attacks, additional checks (e.g audience validation)
                    // are expected to be made by specialized handlers later in the token validation processing.
                    parameters.ValidTypes = null;

                    return(parameters);
                }
            }
        public static OpenIddictConfiguration UseEntityFramework([NotNull] this OpenIddictConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (!IsSubclassOf(configuration.ApplicationType, typeof(Application <>)))
            {
                throw new InvalidOperationException("The default store cannot be used with application " +
                                                    "entities that are not derived from Application<TKey>.");
            }

            configuration.Services.AddScoped(
                typeof(IOpenIddictStore <,>).MakeGenericType(configuration.UserType, configuration.ApplicationType),
                typeof(OpenIddictStore <, , ,>).MakeGenericType(
                    /* TUser: */ configuration.UserType,
                    /* TApplication: */ configuration.ApplicationType,
                    /* TContext: */ ResolveContextType(configuration),
                    /* TKey: */ ResolveKeyType(configuration)));

            return(configuration);
        }