2021-06-15 09:57:28 +01:00
using eShopOnContainers.WebSPA ;
2019-07-23 12:14:09 +02:00
using HealthChecks.UI.Client ;
2016-11-17 10:34:10 +01:00
using Microsoft.AspNetCore.Antiforgery ;
using Microsoft.AspNetCore.Builder ;
2017-11-30 11:40:30 +01:00
using Microsoft.AspNetCore.DataProtection ;
2019-07-23 12:14:09 +02:00
using Microsoft.AspNetCore.Diagnostics.HealthChecks ;
2016-11-17 10:34:10 +01:00
using Microsoft.AspNetCore.Hosting ;
2021-06-15 09:57:28 +01:00
using Microsoft.AspNetCore.Http ;
using Microsoft.AspNetCore.Mvc ;
using Microsoft.AspNetCore.SpaServices.AngularCli ;
2016-11-17 10:34:10 +01:00
using Microsoft.Extensions.Configuration ;
using Microsoft.Extensions.DependencyInjection ;
2019-07-23 12:14:09 +02:00
using Microsoft.Extensions.Diagnostics.HealthChecks ;
2019-11-08 16:02:58 +00:00
using Microsoft.Extensions.Hosting ;
2017-08-29 12:14:10 +02:00
using Microsoft.Extensions.Logging ;
2017-11-30 11:40:30 +01:00
using StackExchange.Redis ;
2017-08-29 12:14:10 +02:00
using System ;
using System.IO ;
2017-06-20 12:54:32 -07:00
using WebSPA.Infrastructure ;
2016-11-17 10:34:10 +01:00
namespace eShopConContainers.WebSPA
{
public class Startup
{
2017-08-29 18:11:30 +02:00
public Startup ( IConfiguration configuration )
{
Configuration = configuration ;
}
public IConfiguration Configuration { get ; }
2019-08-06 08:51:17 +02:00
public Startup ( )
2016-11-17 10:34:10 +01:00
{
2017-03-17 15:38:18 -07:00
var localPath = new Uri ( Configuration [ "ASPNETCORE_URLS" ] ) ? . LocalPath ? ? "/" ;
Configuration [ "BaseUrl" ] = localPath ;
2016-11-17 10:34:10 +01:00
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices ( IServiceCollection services )
{
2017-10-13 11:35:26 +02:00
RegisterAppInsights ( services ) ;
2017-10-11 18:53:26 +02:00
2018-11-30 17:43:22 +01:00
services . AddHealthChecks ( )
2019-01-03 17:11:56 +01:00
. AddCheck ( "self" , ( ) = > HealthCheckResult . Healthy ( ) )
2019-07-23 12:14:09 +02:00
. AddUrlGroup ( new Uri ( Configuration [ "IdentityUrlHC" ] ) , name : "identityapi-check" , tags : new string [ ] { "identityapi" } ) ;
2017-03-28 16:16:01 +02:00
2017-01-10 11:37:36 +01:00
services . Configure < AppSettings > ( Configuration ) ;
2017-06-08 17:45:07 +02:00
if ( Configuration . GetValue < string > ( "IsClusterEnv" ) = = bool . TrueString )
2017-03-15 08:57:01 -07:00
{
2017-06-08 17:45:07 +02:00
services . AddDataProtection ( opts = >
{
opts . ApplicationDiscriminator = "eshop.webspa" ;
} )
2021-01-12 20:38:54 +05:30
. PersistKeysToStackExchangeRedis ( ConnectionMultiplexer . Connect ( Configuration [ "DPConnectionString" ] ) , "DataProtection-Keys" ) ;
2017-06-08 17:45:07 +02:00
}
2017-03-15 08:57:01 -07:00
2021-06-15 09:57:28 +01:00
// Add Antiforgery services and configure the header name that angular will use by default.
2016-11-17 10:34:10 +01:00
services . AddAntiforgery ( options = > options . HeaderName = "X-XSRF-TOKEN" ) ;
2021-06-15 09:57:28 +01:00
// Add controllers support and add a global AutoValidateAntiforgeryTokenFilter that will make the application check for an Antiforgery token on all "mutating" requests (POST, PUT, DELETE).
// The AutoValidateAntiforgeryTokenFilter is an internal class registered when we register views, so we need to register controllers and views also.
services . AddControllersWithViews ( options = > options . Filters . Add ( new AutoValidateAntiforgeryTokenAttribute ( ) ) )
2016-11-17 10:34:10 +01:00
. AddJsonOptions ( options = >
{
2019-07-23 12:14:09 +02:00
options . JsonSerializerOptions . PropertyNameCaseInsensitive = true ;
2016-11-17 10:34:10 +01:00
} ) ;
2021-06-15 09:57:28 +01:00
// Setup where the compiled version of our spa application will be, when in production.
services . AddSpaStaticFiles ( configuration = >
{
configuration . RootPath = "wwwroot" ;
} ) ;
2016-11-17 10:34:10 +01:00
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
2019-11-08 16:02:58 +00:00
public void Configure ( IApplicationBuilder app , IWebHostEnvironment env , ILoggerFactory loggerFactory , IAntiforgery antiforgery )
2016-11-17 10:34:10 +01:00
{
if ( env . IsDevelopment ( ) )
{
app . UseDeveloperExceptionPage ( ) ;
}
2020-12-23 15:19:36 +05:30
2021-06-15 09:57:28 +01:00
// Here we add Angular default Antiforgery cookie name on first load. https://angular.io/guide/http#security-xsrf-protection
// This cookie will be read by Angular app and its value will be sent back to the application as the header configured in .AddAntiforgery()
app . Use ( next = > context = >
{
string path = context . Request . Path . Value ;
if (
string . Equals ( path , "/" , StringComparison . OrdinalIgnoreCase ) | |
string . Equals ( path , "/index.html" , StringComparison . OrdinalIgnoreCase ) )
{
// The request token has to be sent as a JavaScript-readable cookie,
// and Angular uses it by default.
var tokens = antiforgery . GetAndStoreTokens ( context ) ;
context . Response . Cookies . Append ( "XSRF-TOKEN" , tokens . RequestToken ,
new CookieOptions ( ) { HttpOnly = false } ) ;
}
return next ( context ) ;
} ) ;
2017-04-13 13:06:22 -03:00
2017-06-20 12:54:32 -07:00
//Seed Data
WebContextSeed . Seed ( app , env , loggerFactory ) ;
2017-09-07 19:18:53 +02:00
var pathBase = Configuration [ "PATH_BASE" ] ;
2019-08-06 08:51:17 +02:00
2017-09-07 19:18:53 +02:00
if ( ! string . IsNullOrEmpty ( pathBase ) )
{
2019-02-22 15:05:28 +00:00
loggerFactory . CreateLogger < Startup > ( ) . LogDebug ( "Using PATH BASE '{pathBase}'" , pathBase ) ;
2017-09-07 19:18:53 +02:00
app . UsePathBase ( pathBase ) ;
2018-01-22 11:46:18 +01:00
}
2017-04-13 13:06:22 -03:00
app . UseDefaultFiles ( ) ;
2016-11-17 10:34:10 +01:00
app . UseStaticFiles ( ) ;
2021-06-15 09:57:28 +01:00
// this will make the application to respond with the index.html and the rest of the assets present on the configured folder (at AddSpaStaticFiles() (wwwroot))
if ( ! env . IsDevelopment ( ) )
{
app . UseSpaStaticFiles ( ) ;
}
2019-07-23 12:14:09 +02:00
app . UseRouting ( ) ;
app . UseEndpoints ( endpoints = >
{
2019-08-06 16:10:39 +02:00
endpoints . MapDefaultControllerRoute ( ) ;
2019-08-06 08:51:17 +02:00
endpoints . MapControllers ( ) ;
2019-07-23 12:14:09 +02:00
endpoints . MapHealthChecks ( "/liveness" , new HealthCheckOptions
{
Predicate = r = > r . Name . Contains ( "self" )
} ) ;
endpoints . MapHealthChecks ( "/hc" , new HealthCheckOptions ( )
{
Predicate = _ = > true ,
ResponseWriter = UIResponseWriter . WriteHealthCheckUIResponse
} ) ;
} ) ;
2021-06-15 09:57:28 +01:00
// Handles all still unnatended (by any other middleware) requests by returning the default page of the SPA (wwwroot/index.html).
app . UseSpa ( spa = >
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
// the root of the angular app. (Where the package.json lives)
spa . Options . SourcePath = "Client" ;
if ( env . IsDevelopment ( ) )
{
// use the SpaServices extension method for angular, that will make the application to run "ng serve" for us, when in development.
spa . UseAngularCliServer ( npmScript : "start" ) ;
}
} ) ;
2016-11-17 10:34:10 +01:00
}
2017-10-13 11:35:26 +02:00
private void RegisterAppInsights ( IServiceCollection services )
{
services . AddApplicationInsightsTelemetry ( Configuration ) ;
2019-07-23 12:14:09 +02:00
services . AddApplicationInsightsKubernetesEnricher ( ) ;
2017-10-13 11:35:26 +02:00
}
2016-11-17 10:34:10 +01:00
}
}