Example #1
0
        private void SetupProducer()
        {
            if (producer != null)
            {
                return;
            }

            lock (myLock)
            {
                Dispose();
            }

            var config = new ProducerConfig {
                BootstrapServers = kafkaOptions.BootstrapServerUri
            };
            var schemaRegistryConfig = new SchemaRegistryConfig {
                Url = kafkaOptions.SchemaRegistryUri
            };
            var jsonSerializerConfig = new JsonSerializerConfig();

            schemaRegistryClient = new CachedSchemaRegistryClient(schemaRegistryConfig);
            producer             = new ProducerBuilder <Null, T>(config)
                                   .SetValueSerializer(new JsonSerializer <T>(schemaRegistryClient, jsonSerializerConfig))
                                   .Build();
        }
Example #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ConfluentJsonSerializer"/> class.
 /// </summary>
 /// <param name="resolver">An instance of <see cref="IDependencyResolver"/></param>
 /// <param name="serializerConfig">An instance of <see cref="JsonSerializerConfig"/></param>
 public ConfluentJsonSerializer(IDependencyResolver resolver, JsonSerializerConfig serializerConfig = null)
     : this(
         resolver,
         serializerConfig,
         null)
 {
 }
 public TransportApplication(JsonSerializerConfig jsonSerializerConfig,
                             IFlightRepository flightRepository,
                             IScheduleService scheduleService)
 {
     _jsonSerializerConfig = jsonSerializerConfig;
     _flightRepository = flightRepository;
     _scheduleService = scheduleService;
 }
        public DeviceValidatorTests()
        {
            // Global JSON options
            JsonSerializerConfig.Configure();

            // Repository
            _testFilePath = "TestData/googleDevices.json";
        }
Example #5
0
 /// <summary>
 /// Registers a middleware to serialize json messages using schema registry
 /// </summary>
 /// <param name="middlewares">The middleware configuration builder</param>
 /// <param name="config">The protobuf serializer configuration</param>
 /// <typeparam name="TMessage">The message type</typeparam>
 /// <returns></returns>
 public static IProducerMiddlewareConfigurationBuilder AddSchemaRegistryJsonSerializer <TMessage>(
     this IProducerMiddlewareConfigurationBuilder middlewares,
     JsonSerializerConfig config = null)
 {
     return(middlewares.AddSerializer(
                resolver => new ConfluentJsonSerializer(resolver, config),
                _ => new SingleMessageTypeResolver(typeof(TMessage))));
 }
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            JsonSerializerConfig.Configure(GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings);
        }
Example #7
0
        private async Task ConsumeFromKafka(CancellationToken stoppingToken,
                                            string consumerDisplayName,
                                            string consumerGroupId,
                                            string sourceTopic,
                                            Func <ConsumeResult <Ignore, T>, Task> processingCallback)
        {
            var config = new ConsumerConfig
            {
                GroupId          = consumerGroupId,
                BootstrapServers = kafkaOptions.BootstrapServerUri,
                // Note: The AutoOffsetReset property determines the start offset in the event
                // there are not yet any committed offsets for the consumer group for the
                // topic/partitions of interest. By default, offsets are committed
                // automatically, so in this example, consumption will only start from the
                // earliest message in the topic 'my-topic' the first time you run the program.
                AutoOffsetReset = AutoOffsetReset.Latest
            };
            var jsonSerializerConfig = new JsonSerializerConfig();

            using var c = new ConsumerBuilder <Ignore, T>(config)
                          .SetValueDeserializer(new JsonDeserializer <T>(jsonSerializerConfig).AsSyncOverAsync())
                          .Build();
            c.Subscribe(sourceTopic);

            try
            {
                while (!stoppingToken.IsCancellationRequested)
                {
                    try
                    {
                        var cr = c.Consume(stoppingToken);

                        // Set up our distributed trace
                        var spanBuilder = KafkaTracingHelper.ObtainConsumerSpanBuilder(tracer, cr.Message.Headers, $"Consume message in {consumerDisplayName}");
                        using var s = spanBuilder.StartActive(true);

                        await processingCallback(cr);
                    }
                    catch (ConsumeException e)
                    {
                        logger.LogInformation($"Error in consumer {consumerDisplayName} occured: {e.Error.Reason}");
                    }
                    catch (OperationCanceledException)
                    {
                        logger.LogInformation($"Stopping topic consumption for consumer {consumerDisplayName}, cancellation requested");
                        c.Close();
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // Ensure the consumer leaves the group cleanly and final offsets are committed.
                c.Close();
            }
        }
        public GoogleDeviceRepositoryTests()
        {
            // Mocks
            _logMock        = new Mock <ILogger <GoogleDeviceRepository> >();
            _messageHubMock = new Mock <IMessageHub>();

            // Global JSON options
            JsonSerializerConfig.Configure();

            // Repository
            _testFilePath = "TestData/googleDevices.json";
        }
Example #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ConfluentJsonSerializer"/> class.
        /// </summary>
        /// <param name="resolver">An instance of <see cref="IDependencyResolver"/></param>
        /// <param name="serializerConfig">An instance of <see cref="JsonSerializerConfig"/></param>
        /// <param name="schemaGeneratorSettings">An instance of <see cref="JsonSchemaGeneratorSettings"/></param>
        public ConfluentJsonSerializer(
            IDependencyResolver resolver,
            JsonSerializerConfig serializerConfig,
            JsonSchemaGeneratorSettings schemaGeneratorSettings)
        {
            this.schemaRegistryClient =
                resolver.Resolve <ISchemaRegistryClient>() ??
                throw new InvalidOperationException(
                          $"No schema registry configuration was found. Set it using {nameof(ClusterConfigurationBuilderExtensions.WithSchemaRegistry)} on cluster configuration");

            this.serializerConfig        = serializerConfig;
            this.schemaGeneratorSettings = schemaGeneratorSettings;
        }
        public GoogleHomeGraphClientTests()
        {
            // Mocks
            _loggerMock = new Mock <ILogger <GoogleHomeGraphClient> >();
            _httpClient = new HttpClient();

            // Global JSON options
            JsonSerializerConfig.Configure();

            // Service account setup
            _agentUserId    = TestHelper.Configuration["agentUserId"];
            _serviceAccount = JsonConvert.DeserializeObject <ServiceAccount>(File.ReadAllText(@"TestData/serviceAccount.json"));
        }
Example #11
0
        public ExperimentEventsService()
        {
            producerConfig = new ProducerConfig
            {
                BootstrapServers = "localhost:9092"
            };

            schemaRegistryConfig = new SchemaRegistryConfig
            {
                Url = "http://localhost:8081",
                // optional schema registry client properties:
                RequestTimeoutMs = 5000,
                MaxCachedSchemas = 10
            };

            jsonSerializerConfig = new JsonSerializerConfig
            {
                BufferBytes = 100
            };
        }
Example #12
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">Service collection.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            // Global JSON options
            JsonSerializerConfig.Configure();

            // Http client factory registration.
            services.AddHttpClient();

            // Add message hub instance
            services.AddSingleton <IMessageHub>(serviceProvider => MessageHub.Instance);

            // Device configuration from file
            services.AddSingleton(serviceProvider =>
            {
                var deviceConfigFile = Configuration.GetValue <string>("deviceConfigFile");
                return(new GoogleDeviceRepository(
                           serviceProvider.GetRequiredService <ILogger <GoogleDeviceRepository> >(),
                           serviceProvider.GetRequiredService <IMessageHub>(),
                           deviceConfigFile));
            });

            // Build state cache from configuration
            services.AddSingleton(serviceProvider =>
            {
                var topics = serviceProvider.GetService <GoogleDeviceRepository>().GetAll()
                             .Where(device => !device.Disabled)
                             .SelectMany(device => device.Traits)
                             .SelectMany(trait => trait.State.Values)
                             .Select(state => state.Topic)
                             .Distinct()
                             .Where(topic => topic != null);

                return(new StateCache(topics.ToDictionary(x => x, x => string.Empty)));
            });

            // Google Home Graph client
            services.AddSingleton <IHostedService, GoogleHomeGraphService>();
            services.AddSingleton(serviceProvider =>
            {
                ServiceAccount serviceAccount    = null;
                var googleHomeServiceAccountFile = Configuration.GetValue <string>("googleHomeGraph:serviceAccountFile");
                if (!string.IsNullOrEmpty(googleHomeServiceAccountFile) && File.Exists(googleHomeServiceAccountFile))
                {
                    var googleHomeServiceAccountFileContents = File.ReadAllText(googleHomeServiceAccountFile);
                    serviceAccount = JsonConvert.DeserializeObject <ServiceAccount>(googleHomeServiceAccountFileContents);
                }

                return(new GoogleHomeGraphClient(
                           serviceProvider.GetRequiredService <ILogger <GoogleHomeGraphClient> >(),
                           serviceProvider.GetRequiredService <IHttpClientFactory>().CreateClient(),
                           serviceAccount,
                           Configuration.GetValue <string>("googleHomeGraph:agentUserId")));
            });

            // Intent handlers
            services.AddTransient <SyncIntentHandler>();
            services.AddTransient <QueryIntentHandler>();
            services.AddTransient <ExecuteIntentHandler>();
            services.AddTransient <DisconnectIntentHandler>();

            // Setup MQTT hosted service
            services.AddSingleton <IHostedService, MqttService>(serviceProvider =>
            {
                var brokerSettings = new Core.BrokerSettings
                {
                    BrokerIp       = Configuration.GetValue <string>("mqtt:brokerIp"),
                    BrokerPort     = Configuration.GetValue <int>("mqtt:brokerPort"),
                    BrokerUsername = Configuration.GetValue <string>("mqtt:brokerUsername"),
                    BrokerPassword = Configuration.GetValue <string>("mqtt:brokerPassword"),
                    BrokerUseTls   = Configuration.GetValue <bool>("mqtt:brokerUseTls", false)
                };

                return(new MqttService(
                           serviceProvider.GetRequiredService <ILogger <MqttService> >(),
                           serviceProvider.GetRequiredService <IMessageHub>(),
                           brokerSettings,
                           serviceProvider.GetRequiredService <GoogleDeviceRepository>(),
                           serviceProvider.GetRequiredService <StateCache>()));
            });

            // Setup token cleanup hosted service
            services.AddSingleton <IHostedService, TokenCleanupService>();
            services.AddTransient <TokenCleanup>();

            // MVC
            services.AddMvc()
            .AddJsonOptions(opt =>
            {
                opt.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                opt.SerializerSettings.Converters.Add(new StringEnumConverter());
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            // Identity Server 4
            services.AddSingleton <IPersistedGrantStoreWithExpiration, PersistedGrantStore>();
            services.AddSingleton <IPersistedGrantStore>(x => x.GetRequiredService <IPersistedGrantStoreWithExpiration>());

            var publicOrigin = Configuration.GetValue <string>("oauth:publicOrigin");
            var authority    = Configuration.GetValue <string>("oauth:authority");

            var identityServerBuilder = services
                                        .AddIdentityServer(options =>
            {
                options.IssuerUri    = authority;
                options.PublicOrigin = publicOrigin;
            })
                                        .AddInMemoryClients(Clients.Get(Configuration))
                                        .AddInMemoryIdentityResources(Resources.GetIdentityResources(Configuration))
                                        .AddInMemoryApiResources(Resources.GetApiResources(Configuration))
                                        .AddTestUsers(Users.Get(Configuration));

            // Get signing certificates
            var signingCertsSection = Configuration.GetSection("oauth:signingCerts");
            var signingCerts        = signingCertsSection.GetChildren()
                                      .Select(x => new SigningCertificate
            {
                File       = x.GetValue <string>("file"),
                PassPhrase = x.GetValue <string>("passPhrase")
            }).ToList();

            if (signingCerts.Any())
            {
                // Add primary cert
                var primarySigningCert = signingCerts.First();
                if (!File.Exists(primarySigningCert.File))
                {
                    throw new FileNotFoundException($"Signing Certificate '{primarySigningCert.File}' is missing!");
                }

                var cert = !string.IsNullOrEmpty(primarySigningCert.PassPhrase) ?
                           new X509Certificate2(primarySigningCert.File, primarySigningCert.PassPhrase) :
                           new X509Certificate2(primarySigningCert.File);

                identityServerBuilder.AddSigningCredential(cert);

                // Add any verification certs
                for (var i = 1; i < signingCerts.Count(); i++)
                {
                    var oldSigningCert = signingCerts[i];
                    if (!File.Exists(oldSigningCert.File))
                    {
                        throw new FileNotFoundException($"Signing Certificate '{oldSigningCert.File}' is missing!");
                    }

                    var oldCert = !string.IsNullOrEmpty(oldSigningCert.PassPhrase) ?
                                  new X509Certificate2(oldSigningCert.File, oldSigningCert.PassPhrase) :
                                  new X509Certificate2(oldSigningCert.File);

                    identityServerBuilder.AddValidationKey(oldCert);
                }
            }
            else
            {
                identityServerBuilder.AddDeveloperSigningCredential(true, "config/tempkey.rsa");
            }

            // Turn on authorization via Cookie (signin, default) and Bearer (API)
            services
            .AddAuthentication(options =>
            {
                options.DefaultChallengeScheme    = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
            {
                options.LoginPath         = "/Account/Login";
                options.LogoutPath        = "/Account/Logout";
                options.ExpireTimeSpan    = TimeSpan.FromHours(1);
                options.SlidingExpiration = true;
            })
            .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
            {
                options.Authority            = authority;
                options.ApiName              = Configuration.GetValue <string>("oauth:resources:0:resourceName");
                options.RequireHttpsMetadata = Configuration.GetValue <bool>("oauth:requireSSL");
            });
        }
        static async Task Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("Usage: .. bootstrapServers schemaRegistryUrl topicName");
                return;
            }

            string bootstrapServers  = args[0];
            string schemaRegistryUrl = args[1];
            string topicName         = args[2];

            var producerConfig = new ProducerConfig
            {
                BootstrapServers = bootstrapServers
            };

            var schemaRegistryConfig = new SchemaRegistryConfig
            {
                // Note: you can specify more than one schema registry url using the
                // schema.registry.url property for redundancy (comma separated list).
                // The property name is not plural to follow the convention set by
                // the Java implementation.
                Url = schemaRegistryUrl
            };

            var consumerConfig = new ConsumerConfig
            {
                BootstrapServers = bootstrapServers,
                GroupId          = "json-example-consumer-group"
            };

            // Note: Specifying json serializer configuration is optional.
            var jsonSerializerConfig = new JsonSerializerConfig
            {
                BufferBytes = 100
            };

            CancellationTokenSource cts = new CancellationTokenSource();
            var consumeTask             = Task.Run(() =>
            {
                using (var consumer =
                           new ConsumerBuilder <string, User>(consumerConfig)
                           .SetKeyDeserializer(Deserializers.Utf8)
                           .SetValueDeserializer(new JsonDeserializer <User>().AsSyncOverAsync())
                           .SetErrorHandler((_, e) => Console.WriteLine($"Error: {e.Reason}"))
                           .Build())
                {
                    consumer.Subscribe(topicName);

                    try
                    {
                        while (true)
                        {
                            try
                            {
                                var cr   = consumer.Consume(cts.Token);
                                var user = cr.Message.Value;
                                Console.WriteLine($"user name: {user.Name}, favorite number: {user.FavoriteNumber}, favorite color: {user.FavoriteColor}");
                            }
                            catch (ConsumeException e)
                            {
                                Console.WriteLine($"Consume error: {e.Error.Reason}");
                            }
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        consumer.Close();
                    }
                }
            });

            using (var schemaRegistry = new CachedSchemaRegistryClient(schemaRegistryConfig))
                using (var producer =
                           new ProducerBuilder <string, User>(producerConfig)
                           .SetValueSerializer(new JsonSerializer <User>(schemaRegistry, jsonSerializerConfig))
                           .Build())
                {
                    Console.WriteLine($"{producer.Name} producing on {topicName}. Enter first names, q to exit.");

                    long   i = 1;
                    string text;
                    while ((text = Console.ReadLine()) != "q")
                    {
                        User user = new User {
                            Name = text, FavoriteColor = "blue", FavoriteNumber = i++
                        };
                        await producer
                        .ProduceAsync(topicName, new Message <string, User> {
                            Value = user
                        })
                        .ContinueWith(task => task.IsFaulted
                            ? $"error producing message: {task.Exception.Message}"
                            : $"produced to: {task.Result.TopicPartitionOffset}");
                    }
                }

            cts.Cancel();

            using (var schemaRegistry = new CachedSchemaRegistryClient(schemaRegistryConfig))
            {
                // Note: a subject name strategy was not configured, so the default "Topic" was used.
                var schema = await schemaRegistry.GetLatestSchemaAsync(SubjectNameStrategy.Topic.ConstructValueSubjectName(topicName));

                Console.WriteLine("\nThe JSON schema corresponding to the written data:");
                Console.WriteLine(schema.SchemaString);
            }
        }
Example #14
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">Service collection.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            // Global JSON options
            JsonSerializerConfig.Configure();

            // Http client factory registration.
            services.AddHttpClient();

            // Add message hub instance
            services.AddSingleton <IMessageHub, MessageHub>();

            // Device configuration from file
            services.AddSingleton <IGoogleDeviceRepository>(serviceProvider =>
            {
                var deviceConfigFile = Configuration.GetValue <string>("deviceConfigFile");
                return(new GoogleDeviceRepository(
                           serviceProvider.GetRequiredService <ILogger <GoogleDeviceRepository> >(),
                           serviceProvider.GetRequiredService <IMessageHub>(),
                           deviceConfigFile));
            });

            // Build state cache from configuration
            services.AddSingleton(serviceProvider =>
            {
                var topics = serviceProvider.GetService <IGoogleDeviceRepository>().GetAll()
                             .Where(device => !device.Disabled)
                             .SelectMany(device => device.Traits)
                             .Where(trait => trait.State != null)
                             .SelectMany(trait => trait.State.Values)
                             .Select(state => state.Topic)
                             .Distinct()
                             .Where(topic => topic != null);

                return(new StateCache(topics.ToDictionary(x => x, x => string.Empty)));
            });

            // Google Home Graph client
            services.AddSingleton <IHostedService, GoogleHomeGraphService>();
            services.AddSingleton(serviceProvider =>
            {
                ServiceAccount serviceAccount    = null;
                var googleHomeServiceAccountFile = Configuration.GetValue <string>("googleHomeGraph:serviceAccountFile");
                if (!string.IsNullOrEmpty(googleHomeServiceAccountFile) && File.Exists(googleHomeServiceAccountFile))
                {
                    var googleHomeServiceAccountFileContents = File.ReadAllText(googleHomeServiceAccountFile);
                    serviceAccount = JsonConvert.DeserializeObject <ServiceAccount>(googleHomeServiceAccountFileContents);
                }

                return(new GoogleHomeGraphClient(
                           serviceProvider.GetRequiredService <ILogger <GoogleHomeGraphClient> >(),
                           serviceProvider.GetRequiredService <IHttpClientFactory>().CreateClient(),
                           serviceAccount,
                           Configuration.GetValue <string>("googleHomeGraph:agentUserId")));
            });

            // Intent handlers
            services.AddTransient <SyncIntentHandler>();
            services.AddTransient <QueryIntentHandler>();
            services.AddTransient <ExecuteIntentHandler>();
            services.AddTransient <DisconnectIntentHandler>();

            // Setup MQTT hosted service
            services.AddSingleton <IHostedService, MqttService>(serviceProvider =>
            {
                var brokerSettings = new Core.BrokerSettings
                {
                    BrokerIp       = Configuration.GetValue <string>("mqtt:brokerIp"),
                    BrokerPort     = Configuration.GetValue <int>("mqtt:brokerPort"),
                    BrokerUsername = Configuration.GetValue <string>("mqtt:brokerUsername"),
                    BrokerPassword = Configuration.GetValue <string>("mqtt:brokerPassword"),
                    BrokerUseTls   = Configuration.GetValue <bool>("mqtt:brokerUseTls", false)
                };

                // TLS settings
                if (brokerSettings.BrokerUseTls)
                {
                    var brokerTlsSettings = new Core.BrokerTlsSettings
                    {
                        AllowUntrustedCertificates        = Configuration.GetValue <bool>("mqtt:brokerTlsSettings:allowUntrustedCertificates", false),
                        IgnoreCertificateChainErrors      = Configuration.GetValue <bool>("mqtt:brokerTlsSettings:ignoreCertificateChainErrors", false),
                        IgnoreCertificateRevocationErrors = Configuration.GetValue <bool>("mqtt:brokerTlsSettings:ignoreCertificateRevocationErrors", false)
                    };

                    switch (Configuration.GetValue <string>("mqtt:brokerTlsSettings:protocol", "1.2"))
                    {
                    case "1.0":
                        brokerTlsSettings.SslProtocol = System.Security.Authentication.SslProtocols.Tls;
                        break;

                    case "1.1":
                        brokerTlsSettings.SslProtocol = System.Security.Authentication.SslProtocols.Tls11;
                        break;

                    case "1.2":
                    default:
                        brokerTlsSettings.SslProtocol = System.Security.Authentication.SslProtocols.Tls12;
                        break;
                    }

                    var brokerTlsCertificatesSection = Configuration.GetSection("mqtt:brokerTlsSettings:certificates");
                    brokerTlsSettings.Certificates   = brokerTlsCertificatesSection.GetChildren()
                                                       .Select(x =>
                    {
                        var file       = x.GetValue <string>("file");
                        var passPhrase = x.GetValue <string>("passPhrase");

                        if (!File.Exists(file))
                        {
                            throw new FileNotFoundException($"Broker Certificate '{file}' is missing!");
                        }

                        return(!string.IsNullOrEmpty(passPhrase) ?
                               new X509Certificate2(file, passPhrase) :
                               new X509Certificate2(file));
                    }).ToList();

                    brokerSettings.BrokerTlsSettings = brokerTlsSettings;
                }

                return(new MqttService(
                           serviceProvider.GetRequiredService <ILogger <MqttService> >(),
                           serviceProvider.GetRequiredService <IMessageHub>(),
                           brokerSettings,
                           serviceProvider.GetRequiredService <IGoogleDeviceRepository>(),
                           serviceProvider.GetRequiredService <StateCache>(),
                           Configuration.GetValue <string>("mqtt:topicRoot", "google/home")));
            });

            // Setup token cleanup hosted service
            services.AddSingleton <IHostedService, TokenCleanupService>();
            services.AddTransient <TokenCleanup>();

            // MVC
            services
            .AddControllersWithViews()
            .AddNewtonsoftJson(opt =>
            {
                opt.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                opt.SerializerSettings.Converters.Add(new StringEnumConverter());
                opt.SerializerSettings.FloatParseHandling = FloatParseHandling.Decimal;
                opt.SerializerSettings.ContractResolver   = new CamelCasePropertyNamesContractResolver {
                    NamingStrategy = new CamelCaseNamingStrategy {
                        ProcessDictionaryKeys = false
                    }
                };
            });

            // Proxy header forwarding
            services.Configure <ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
                options.KnownNetworks.Clear();
                options.KnownProxies.Clear();
            });

            // Identity Server 4
            services.AddSingleton <IPersistedGrantStoreWithExpiration, PersistedGrantStore>();
            services.AddSingleton <IPersistedGrantStore>(serviceProvider => serviceProvider.GetRequiredService <IPersistedGrantStoreWithExpiration>());
            services.AddTransient <IRefreshTokenService>(serviceProvider => new GracefulRefreshTokenService(
                                                             serviceProvider.GetRequiredService <IRefreshTokenStore>(),
                                                             serviceProvider.GetRequiredService <IProfileService>(),
                                                             serviceProvider.GetRequiredService <ISystemClock>(),
                                                             serviceProvider.GetRequiredService <ILogger <GracefulRefreshTokenService> >(),
                                                             Configuration.GetValue("oauth:refreshTokenGracePeriod", 0)));

            var authority             = Configuration.GetValue <string>("oauth:authority");
            var identityServerBuilder = services
                                        .AddIdentityServer(options =>
            {
                options.IssuerUri = authority;
            })
                                        .AddInMemoryClients(Clients.Get(Configuration))
                                        .AddInMemoryIdentityResources(Resources.GetIdentityResources())
                                        .AddInMemoryApiScopes(Resources.GetApiScopes())
                                        .AddTestUsers(Users.Get(Configuration));

            // Get signing certificates
            var signingCertsSection = Configuration.GetSection("oauth:signingCerts");
            var signingCerts        = signingCertsSection.GetChildren()
                                      .Select(x => new SigningCertificate
            {
                File       = x.GetValue <string>("file"),
                PassPhrase = x.GetValue <string>("passPhrase")
            }).ToList();

            if (signingCerts.Any())
            {
                // Add primary cert
                var primarySigningCert = signingCerts.First();
                if (!File.Exists(primarySigningCert.File))
                {
                    throw new FileNotFoundException($"Signing Certificate '{primarySigningCert.File}' is missing!");
                }

                var cert = !string.IsNullOrEmpty(primarySigningCert.PassPhrase) ?
                           new X509Certificate2(primarySigningCert.File, primarySigningCert.PassPhrase) :
                           new X509Certificate2(primarySigningCert.File);

                identityServerBuilder.AddSigningCredential(cert);

                // Add any verification certs
                for (var i = 1; i < signingCerts.Count; i++)
                {
                    var oldSigningCert = signingCerts[i];
                    if (!File.Exists(oldSigningCert.File))
                    {
                        throw new FileNotFoundException($"Signing Certificate '{oldSigningCert.File}' is missing!");
                    }

                    var oldCert = !string.IsNullOrEmpty(oldSigningCert.PassPhrase) ?
                                  new X509Certificate2(oldSigningCert.File, oldSigningCert.PassPhrase) :
                                  new X509Certificate2(oldSigningCert.File);

                    identityServerBuilder.AddValidationKey(oldCert);
                }
            }
            else
            {
                identityServerBuilder.AddDeveloperSigningCredential(true, "config/tempkey.jwk");
            }

            // Turn on authorization via Cookie (signin, default) and Bearer (API)
            services
            .AddAuthentication(options =>
            {
                options.DefaultChallengeScheme    = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
            {
                options.LoginPath         = "/Account/Login";
                options.LogoutPath        = "/Account/Logout";
                options.ExpireTimeSpan    = TimeSpan.FromHours(1);
                options.SlidingExpiration = true;
            })
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                options.RequireHttpsMetadata = Configuration.GetValue <bool>("oauth:requireSSL");
                options.Authority            = authority;

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = false
                };
            });
        }
Example #15
0
 public static IServiceCollection AddJsonSerializer
     (this IServiceCollection services,
     JsonSerializerConfig serializerConfig) =>
 services.AddSingleton(p => CreateJsonSerializer(serializerConfig));