Example #1
0
        // 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;
            });
        }