// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // add a singleton for data access. string connectionString = DatabaseTools.GetConnectionString(Configuration); string databaseName = DatabaseTools.GetDatabaseName(Configuration); DatabaseTools.CreateDatabaseIfNotExists(Configuration); services.AddDbContext <AppDbContext>( options => options.UseSqlServer(connectionString)); // add singleton to allow Controllers to query the Request object services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); // determine if we wire up Dynamics. if (!string.IsNullOrEmpty(Configuration["DYNAMICS_ODATA_URI"])) { SetupDynamics(services); } // Add a memory cache services.AddMemoryCache(); // for security reasons, the following headers are set. services.AddMvc(opts => { // default deny var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); opts.Filters.Add(new AuthorizeFilter(policy)); opts.Filters.Add(typeof(NoCacheHttpHeadersAttribute)); opts.Filters.Add(new XRobotsTagAttribute() { NoIndex = true, NoFollow = true }); opts.Filters.Add(typeof(XContentTypeOptionsAttribute)); opts.Filters.Add(typeof(XDownloadOptionsAttribute)); opts.Filters.Add(typeof(XFrameOptionsAttribute)); opts.Filters.Add(typeof(XXssProtectionAttribute)); //CSPReportOnly opts.Filters.Add(typeof(CspReportOnlyAttribute)); opts.Filters.Add(new CspScriptSrcReportOnlyAttribute { None = true }); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .AddJsonOptions( opts => { opts.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; opts.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat; opts.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc; // ReferenceLoopHandling is set to Ignore to prevent JSON parser issues with the user / roles model. opts.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; }); // setup siteminder authentication (core 2.0) services.AddAuthentication(options => { options.DefaultAuthenticateScheme = SiteMinderAuthOptions.AuthenticationSchemeName; options.DefaultChallengeScheme = SiteMinderAuthOptions.AuthenticationSchemeName; }).AddSiteminderAuth(options => { }); // setup authorization services.AddAuthorization(options => { options.AddPolicy("Business-User", policy => policy.RequireClaim(User.UserTypeClaim, "Business")); }); services.RegisterPermissionHandler(); // setup key ring to persist in storage. services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(Configuration["KEY_RING_DIRECTORY"])); // In production, the Angular files will be served from this directory services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/dist"; }); // allow for large files to be uploaded services.Configure <FormOptions>(options => { options.MultipartBodyLengthLimit = 1073741824; // 1 GB }); // health checks services.AddHealthChecks(checks => { checks.AddValueTaskCheck("HTTP Endpoint", () => new ValueTask <IHealthCheckResult>(HealthCheckResult.Healthy("Ok"))); checks.AddSqlCheck(DatabaseTools.GetDatabaseName(Configuration), DatabaseTools.GetConnectionString(Configuration)); }); services.AddSession(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // add a singleton for data access. #if (USE_MSSQL) string connectionString = DatabaseTools.GetConnectionString(Configuration); string databaseName = DatabaseTools.GetDatabaseName(Configuration); DatabaseTools.CreateDatabaseIfNotExists(Configuration); services.AddDbContext <AppDbContext>( options => options.UseSqlServer(connectionString)); #endif // add singleton to allow Controllers to query the Request object services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); // determine if we wire up Dynamics. if (!string.IsNullOrEmpty(_configuration["DYNAMICS_ODATA_URI"])) { SetupServices(services); } // Add a memory cache services.AddMemoryCache(); // for security reasons, the following headers are set. services.AddMvc(opts => { opts.EnableEndpointRouting = false; // default deny var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); opts.Filters.Add(new AuthorizeFilter(policy)); opts.Filters.Add(typeof(NoCacheHttpHeadersAttribute)); opts.Filters.Add(new XRobotsTagAttribute() { NoIndex = true, NoFollow = true }); opts.Filters.Add(typeof(XContentTypeOptionsAttribute)); opts.Filters.Add(typeof(XDownloadOptionsAttribute)); opts.Filters.Add(typeof(XFrameOptionsAttribute)); opts.Filters.Add(typeof(XXssProtectionAttribute)); //CSPReportOnly opts.Filters.Add(typeof(CspReportOnlyAttribute)); opts.Filters.Add(new CspScriptSrcReportOnlyAttribute { None = true }); }) .AddNewtonsoftJson(opts => { opts.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; opts.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat; opts.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc; // ReferenceLoopHandling is set to Ignore to prevent JSON parser issues with the user / roles model. opts.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; }) .SetCompatibilityVersion(CompatibilityVersion.Version_3_0); // setup siteminder authentication (core 2.0) services.AddAuthentication(options => { options.DefaultAuthenticateScheme = SiteMinderAuthOptions.AuthenticationSchemeName; options.DefaultChallengeScheme = SiteMinderAuthOptions.AuthenticationSchemeName; }).AddSiteminderAuth(options => { }); // setup authorization services.AddAuthorization(options => { // This policy is used for existing business accounts options.AddPolicy("Business-User", policy => policy.RequireAssertion(context => { var res = context.User.HasClaim(c => c.Type == User.UserTypeClaim && c.Value == "Business") && context.User.HasClaim(c => c.Type == User.PermissionClaim && c.Value == Permission.ExistingUser); return(res); })); // This policy is used for existing business accounts and also during account registration options.AddPolicy("Can-Create-Account", policy => policy.RequireAssertion(context => { var res = context.User.HasClaim(c => c.Type == User.UserTypeClaim && c.Value == "Business") && (context.User.HasClaim(c => c.Type == User.PermissionClaim && c.Value == Permission.ExistingUser) || context.User.HasClaim(c => c.Type == User.PermissionClaim && c.Value == Permission.NewUserRegistration)); return(res); })); }); services.RegisterPermissionHandler(); if (!string.IsNullOrEmpty(_configuration["KEY_RING_DIRECTORY"])) { // setup key ring to persist in storage. services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(_configuration["KEY_RING_DIRECTORY"])); } // In production, the Angular files will be served from this directory services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/dist"; }); // allow for large files to be uploaded services.Configure <FormOptions>(options => { options.MultipartBodyLengthLimit = 1073741824; // 1 GB }); var orgBook = new OrgBookClient(new HttpClient()); orgBook.ReadResponseAsString = true; services.AddTransient <IOrgBookClient>(_ => (IOrgBookClient)orgBook); if (!string.IsNullOrEmpty(_configuration["REDIS_SERVER"])) { string config = _configuration["REDIS_SERVER"]; if (!string.IsNullOrEmpty(_configuration["REDIS_PASSWORD"])) { string redisPassword = _configuration["REDIS_PASSWORD"]; config += $",password={redisPassword}"; } services.AddDistributedRedisCache(o => { o.Configuration = config; }); // health checks services.AddHealthChecks() .AddCheck("cllc_public_app", () => HealthCheckResult.Healthy()) // No longer checking SQL Server in health checks as the SQL components are no longer active. #if (USE_MSSQL) .AddSqlServer(DatabaseTools.GetConnectionString(Configuration), name: "Sql server") #endif .AddRedis(config, name: "Redis") .AddCheck <DynamicsHealthCheck>("Dynamics") .AddCheck <GeocoderHealthCheck>("Geocoder"); } else // checks with no redis. { // health checks services.AddHealthChecks() .AddCheck("cllc_public_app", () => HealthCheckResult.Healthy()) // No longer checking SQL Server in health checks as the SQL components are no longer active. #if (USE_MSSQL) .AddSqlServer(DatabaseTools.GetConnectionString(Configuration), name: "Sql server") #endif .AddCheck <DynamicsHealthCheck>("Dynamics") .AddCheck <GeocoderHealthCheck>("Geocoder"); } // session will automatically use redis or another distributed cache if it is available. services.AddSession(x => { x.IdleTimeout = TimeSpan.FromHours(4.0); x.Cookie.IsEssential = true; }); }