Make WebMVC use the service common helpers
This commit is contained in:
parent
40315c69d7
commit
8c2ca8dbd9
86
src/Web/WebMVC/Extensions/Extensions.cs
Normal file
86
src/Web/WebMVC/Extensions/Extensions.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used
|
||||||
|
// Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391
|
||||||
|
internal static class Extensions
|
||||||
|
{
|
||||||
|
public static void AddHealthChecks(this WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Services.AddHealthChecks()
|
||||||
|
.AddUrlGroup(_ => new Uri(builder.Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddApplicationSevices(this WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Services.Configure<AppSettings>(builder.Configuration)
|
||||||
|
.AddSession()
|
||||||
|
.AddDistributedMemoryCache();
|
||||||
|
|
||||||
|
if (builder.Configuration["DPConnectionString"] is string redisConnection)
|
||||||
|
{
|
||||||
|
builder.Services.AddDataProtection(opts =>
|
||||||
|
{
|
||||||
|
opts.ApplicationDiscriminator = "eshop.webmvc";
|
||||||
|
})
|
||||||
|
.PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect(redisConnection), "DataProtection-Keys");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds all Http client services
|
||||||
|
public static void AddHttpClientServices(this WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
// Register delegating handlers
|
||||||
|
builder.Services.AddTransient<HttpClientAuthorizationDelegatingHandler>()
|
||||||
|
.AddTransient<HttpClientRequestIdDelegatingHandler>();
|
||||||
|
|
||||||
|
// Add http client services
|
||||||
|
builder.Services.AddHttpClient<IBasketService, BasketService>()
|
||||||
|
.SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes
|
||||||
|
.AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>();
|
||||||
|
|
||||||
|
builder.Services.AddHttpClient<ICatalogService, CatalogService>();
|
||||||
|
|
||||||
|
builder.Services.AddHttpClient<IOrderingService, OrderingService>()
|
||||||
|
.AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>()
|
||||||
|
.AddHttpMessageHandler<HttpClientRequestIdDelegatingHandler>();
|
||||||
|
|
||||||
|
|
||||||
|
//add custom application services
|
||||||
|
builder.Services.AddTransient<IIdentityParser<ApplicationUser>, IdentityParser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddAuthenticationServices(this WebApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
|
||||||
|
|
||||||
|
var identityUrl = builder.Configuration.GetRequiredValue("IdentityUrl");
|
||||||
|
var callBackUrl = builder.Configuration.GetRequiredValue("CallBackUrl");
|
||||||
|
var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60);
|
||||||
|
|
||||||
|
// Add Authentication services
|
||||||
|
|
||||||
|
builder.Services.AddAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||||
|
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
|
||||||
|
})
|
||||||
|
.AddCookie(options => options.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime))
|
||||||
|
.AddOpenIdConnect(options =>
|
||||||
|
{
|
||||||
|
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||||
|
options.Authority = identityUrl;
|
||||||
|
options.SignedOutRedirectUri = callBackUrl;
|
||||||
|
options.ClientId = "mvc";
|
||||||
|
options.ClientSecret = "secret";
|
||||||
|
options.ResponseType = "code";
|
||||||
|
options.SaveTokens = true;
|
||||||
|
options.GetClaimsFromUserInfoEndpoint = true;
|
||||||
|
options.RequireHttpsMetadata = false;
|
||||||
|
options.Scope.Add("openid");
|
||||||
|
options.Scope.Add("profile");
|
||||||
|
options.Scope.Add("orders");
|
||||||
|
options.Scope.Add("basket");
|
||||||
|
options.Scope.Add("webshoppingagg");
|
||||||
|
options.Scope.Add("orders.signalrhub");
|
||||||
|
options.Scope.Add("webhooks");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,34 +1,21 @@
|
|||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.AddServiceDefaults();
|
||||||
|
|
||||||
builder.Services.AddControllersWithViews();
|
builder.Services.AddControllersWithViews();
|
||||||
|
|
||||||
AddApplicationInsights(builder);
|
builder.AddHealthChecks();
|
||||||
AddHealthChecks(builder);
|
builder.AddApplicationSevices();
|
||||||
AddCustomMvc(builder);
|
builder.AddHttpClientServices();
|
||||||
AddHttpClientServices(builder);
|
builder.AddAuthenticationServices();
|
||||||
AddCustomAuthentication(builder);
|
|
||||||
|
|
||||||
builder.WebHost.CaptureStartupErrors(false);
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
|
app.UseServiceDefaults();
|
||||||
if (!app.Environment.IsDevelopment())
|
|
||||||
{
|
|
||||||
app.UseExceptionHandler("/Error");
|
|
||||||
}
|
|
||||||
|
|
||||||
var pathBase = builder.Configuration["PATH_BASE"];
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(pathBase))
|
|
||||||
{
|
|
||||||
app.UsePathBase(pathBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
app.UseSession();
|
app.UseSession();
|
||||||
|
|
||||||
WebContextSeed.Seed(app, app.Environment);
|
|
||||||
|
|
||||||
// Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used
|
// Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used
|
||||||
// Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391
|
// Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391
|
||||||
app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Lax });
|
app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Lax });
|
||||||
@ -41,106 +28,7 @@ app.UseAuthorization();
|
|||||||
app.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}");
|
app.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}");
|
||||||
app.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}");
|
app.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}");
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
app.MapHealthChecks("/liveness", new HealthCheckOptions
|
|
||||||
{
|
WebContextSeed.Seed(app, app.Environment);
|
||||||
Predicate = r => r.Name.Contains("self")
|
|
||||||
});
|
|
||||||
app.MapHealthChecks("/hc", new HealthCheckOptions()
|
|
||||||
{
|
|
||||||
Predicate = _ => true,
|
|
||||||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
|
||||||
});
|
|
||||||
|
|
||||||
await app.RunAsync();
|
await app.RunAsync();
|
||||||
|
|
||||||
static void AddApplicationInsights(WebApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
builder.Services.AddApplicationInsightsTelemetry(builder.Configuration);
|
|
||||||
builder.Services.AddApplicationInsightsKubernetesEnricher();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AddHealthChecks(WebApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
builder.Services.AddHealthChecks()
|
|
||||||
.AddCheck("self", () => HealthCheckResult.Healthy())
|
|
||||||
.AddUrlGroup(_ => new Uri(builder.Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" });
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AddCustomMvc(WebApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
builder.Services.Configure<AppSettings>(builder.Configuration)
|
|
||||||
.AddSession()
|
|
||||||
.AddDistributedMemoryCache();
|
|
||||||
|
|
||||||
if (builder.Configuration.GetValue<string>("IsClusterEnv") == bool.TrueString)
|
|
||||||
{
|
|
||||||
builder.Services.AddDataProtection(opts =>
|
|
||||||
{
|
|
||||||
opts.ApplicationDiscriminator = "eshop.webmvc";
|
|
||||||
})
|
|
||||||
.PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect(builder.Configuration["DPConnectionString"]), "DataProtection-Keys");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds all Http client services
|
|
||||||
static void AddHttpClientServices(WebApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
builder.Services.AddHttpContextAccessor();
|
|
||||||
|
|
||||||
//register delegating handlers
|
|
||||||
builder.Services.AddTransient<HttpClientAuthorizationDelegatingHandler>()
|
|
||||||
.AddTransient<HttpClientRequestIdDelegatingHandler>();
|
|
||||||
|
|
||||||
//set 5 min as the lifetime for each HttpMessageHandler int the pool
|
|
||||||
builder.Services.AddHttpClient("extendedhandlerlifetime").SetHandlerLifetime(TimeSpan.FromMinutes(5));
|
|
||||||
|
|
||||||
//add http client services
|
|
||||||
builder.Services.AddHttpClient<IBasketService, BasketService>()
|
|
||||||
.SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes
|
|
||||||
.AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>();
|
|
||||||
|
|
||||||
builder.Services.AddHttpClient<ICatalogService, CatalogService>();
|
|
||||||
|
|
||||||
builder.Services.AddHttpClient<IOrderingService, OrderingService>()
|
|
||||||
.AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>()
|
|
||||||
.AddHttpMessageHandler<HttpClientRequestIdDelegatingHandler>();
|
|
||||||
|
|
||||||
|
|
||||||
//add custom application services
|
|
||||||
builder.Services.AddTransient<IIdentityParser<ApplicationUser>, IdentityParser>();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AddCustomAuthentication(WebApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
|
|
||||||
var callBackUrl = builder.Configuration.GetValue<string>("CallBackUrl");
|
|
||||||
var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60);
|
|
||||||
|
|
||||||
// Add Authentication services
|
|
||||||
|
|
||||||
builder.Services.AddAuthentication(options =>
|
|
||||||
{
|
|
||||||
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
|
|
||||||
})
|
|
||||||
.AddCookie(setup => setup.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime))
|
|
||||||
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
|
|
||||||
{
|
|
||||||
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
|
||||||
options.Authority = identityUrl.ToString();
|
|
||||||
options.SignedOutRedirectUri = callBackUrl.ToString();
|
|
||||||
options.ClientId = "mvc";
|
|
||||||
options.ClientSecret = "secret";
|
|
||||||
options.ResponseType = "code";
|
|
||||||
options.SaveTokens = true;
|
|
||||||
options.GetClaimsFromUserInfoEndpoint = true;
|
|
||||||
options.RequireHttpsMetadata = false;
|
|
||||||
options.Scope.Add("openid");
|
|
||||||
options.Scope.Add("profile");
|
|
||||||
options.Scope.Add("orders");
|
|
||||||
options.Scope.Add("basket");
|
|
||||||
options.Scope.Add("webshoppingagg");
|
|
||||||
options.Scope.Add("orders.signalrhub");
|
|
||||||
options.Scope.Add("webhooks");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
<UserSecretsId>aspnet-Microsoft.eShopOnContainers-946ae052-8305-4a99-965b-ec8636ddbae3</UserSecretsId>
|
<UserSecretsId>aspnet-Microsoft.eShopOnContainers-946ae052-8305-4a99-965b-ec8636ddbae3</UserSecretsId>
|
||||||
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||||
<TypeScriptToolsVersion>3.0</TypeScriptToolsVersion>
|
<TypeScriptToolsVersion>3.0</TypeScriptToolsVersion>
|
||||||
<GenerateErrorForMissingTargetingPacks>false</GenerateErrorForMissingTargetingPacks>
|
|
||||||
<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -24,21 +22,12 @@
|
|||||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" />
|
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.Uris" />
|
<PackageReference Include="AspNetCore.HealthChecks.Uris" />
|
||||||
<PackageReference Include="BuildBundlerMinifier" />
|
<PackageReference Include="BuildBundlerMinifier" />
|
||||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" />
|
|
||||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" />
|
|
||||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" />
|
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.HealthChecks" />
|
|
||||||
<PackageReference Include="Microsoft.Build.Utilities.Core" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" />
|
|
||||||
<PackageReference Include="Microsoft.Web.LibraryManager.Build" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="ViewModels\CampaignItem.cs" />
|
<ProjectReference Include="..\..\Services\Services.Common\Services.Common.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
"PurchaseUrl": "http://localhost:5229",
|
"PurchaseUrl": "http://localhost:5229",
|
||||||
"SignalrHubUrl": "http://localhost:5229",
|
"SignalrHubUrl": "http://localhost:5229",
|
||||||
"IdentityUrl": "http://localhost:5223",
|
"IdentityUrl": "http://localhost:5223",
|
||||||
|
@ -15,14 +15,12 @@ global using System.Text.Json;
|
|||||||
global using System.Text.Json.Serialization;
|
global using System.Text.Json.Serialization;
|
||||||
global using System.Threading;
|
global using System.Threading;
|
||||||
global using System.Threading.Tasks;
|
global using System.Threading.Tasks;
|
||||||
global using HealthChecks.UI.Client;
|
|
||||||
global using Microsoft.AspNetCore.Authentication;
|
global using Microsoft.AspNetCore.Authentication;
|
||||||
global using Microsoft.AspNetCore.Authentication.Cookies;
|
global using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
global using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
global using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||||
global using Microsoft.AspNetCore.Authorization;
|
global using Microsoft.AspNetCore.Authorization;
|
||||||
global using Microsoft.AspNetCore.Builder;
|
global using Microsoft.AspNetCore.Builder;
|
||||||
global using Microsoft.AspNetCore.DataProtection;
|
global using Microsoft.AspNetCore.DataProtection;
|
||||||
global using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
|
||||||
global using Microsoft.AspNetCore.Hosting;
|
global using Microsoft.AspNetCore.Hosting;
|
||||||
global using Microsoft.AspNetCore.Http;
|
global using Microsoft.AspNetCore.Http;
|
||||||
global using Microsoft.AspNetCore.Identity;
|
global using Microsoft.AspNetCore.Identity;
|
||||||
@ -37,10 +35,9 @@ global using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels;
|
|||||||
global using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
|
global using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
|
||||||
global using Microsoft.Extensions.Configuration;
|
global using Microsoft.Extensions.Configuration;
|
||||||
global using Microsoft.Extensions.DependencyInjection;
|
global using Microsoft.Extensions.DependencyInjection;
|
||||||
global using Microsoft.Extensions.Diagnostics.HealthChecks;
|
|
||||||
global using Microsoft.Extensions.Hosting;
|
|
||||||
global using Microsoft.Extensions.Logging;
|
global using Microsoft.Extensions.Logging;
|
||||||
global using Microsoft.Extensions.Options;
|
global using Microsoft.Extensions.Options;
|
||||||
|
global using Services.Common;
|
||||||
global using StackExchange.Redis;
|
global using StackExchange.Redis;
|
||||||
global using WebMVC.Infrastructure;
|
global using WebMVC.Infrastructure;
|
||||||
global using WebMVC.Services.ModelDTOs;
|
global using WebMVC.Services.ModelDTOs;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user