rafsanulhasan e23e8c641e a. Project files
1. Specified RuntimeFrameworkVersion to 2.1.3
    2. Specified Microsoft.AspNetCore.App meta package version to 2.1.3
    3. Updated NuGetPackages to support ASP.NET Core 2.1.3
        i. Microsoft.AspNetCore.Hosting 2.1.0->2.1.1
        ii. Microsoft.EntityFrameworkCore, Microsoft.EntityFrameworkCore.Design, Microsoft.EntityFrameworkCore.Relational, Microsoft.EntityFrameworkCore.SqlServer 2.1.0->2.1.2
        iii.Microsoft.Extensions.Logging 2.1.0->2.1.1
        iv. Microsoft.ApplicationInsights.AspNetCore 2.2.1->2.4.1
        v. Microsoft.ApplicationInsights.DependencyCollector 2.6.1-> 2.7.2
        vi. Microsoft.ApplicationInsights.ServiceFabric 2.1.1-beta1->2.1.1
        vii. Microsoft.Extensions.Logging.AzureAppServices 2.1.0-> 2.1.1
        viii. Microsoft.AspNetCore.App 2.1.0->2.1.3
        ix. Microsoft.VisualStudio.Azure.Fabric.MSBuild 1.6.5->1.6.7
        x. Microsoft.AspNetCore.SignalR, Microsoft.AspNetCore.SignalR.Core, Microsoft.AspNetCore.SignalR.Redis 1.0.0->1.0.3
    4. Updated NuGetPackages
        i. System.Threading.Tasks.Extensions 4.5.0->4.5.1
        ii. WindowsAzure.Storage 9.1.0->9.3.1
b. DockerFile
    1.  Updated SDK version to 2.1.401
    2. Updated Runtime version to 2.1.3
c. Startup.cs file
    1. SetCompatibilityVersion to 2.1 in MVC pipeline (Line 83)
    2. Suppress compiler warning
    3. Re-factored coding styles
d. appsettings.json
    1. Updated IdentityUrl to use HTTPS endpoint
e. launchsettings.json
    1. Used 64bit IIS Express bitness
2018-09-01 05:17:12 +06:00

195 lines
6.2 KiB
C#

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Polly;
using Polly.Extensions.Http;
using Swashbuckle.AspNetCore.Swagger;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services
.AddCustomMvc(Configuration)
.AddCustomAuthentication(Configuration)
.AddHttpServices();
//services.AddHttpsRedirection(opts =>
//{
// opts.HttpsPort = 4120;
//});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
string pathBase = Configuration["PATH_BASE"];
if (!string.IsNullOrEmpty(pathBase))
{
loggerFactory.CreateLogger("init").LogDebug($"Using PATH BASE '{pathBase}'");
app.UsePathBase(pathBase);
}
app.UseCors("CorsPolicy");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
app.UseSwagger().UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1");
c.ConfigureOAuth2("Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI");
});
}
}
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration)
{
services.AddOptions();
services.Configure<UrlsConfig>(configuration.GetSection("urls"));
services
.AddMvc()
.SetCompatibilityVersion(AspNetCore.Mvc.CompatibilityVersion.Version_2_1)
;
services.AddSwaggerGen(options =>
{
options.DescribeAllEnumsAsStrings();
options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
{
Title = "Shopping Aggregator for Mobile Clients",
Version = "v1",
Description = "Shopping Aggregator for Mobile Clients",
TermsOfService = "Terms Of Service"
});
options.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "implicit",
AuthorizationUrl = $"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize",
TokenUrl = $"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/token",
Scopes = new Dictionary<string, string>()
{
{ "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" }
}
});
options.OperationFilter<AuthorizeCheckOperationFilter>();
});
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
return services;
}
public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
var identityUrl = configuration.GetValue<string>("urls:identity");
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = identityUrl;
options.RequireHttpsMetadata = false;
options.Audience = "mobileshoppingagg";
options.Events = new JwtBearerEvents()
{
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
OnAuthenticationFailed = async ctx =>
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
},
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
OnTokenValidated = async ctx =>
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
}
};
});
return services;
}
public static IServiceCollection AddHttpServices(this IServiceCollection services)
{
//register delegating handlers
services.AddTransient<HttpClientAuthorizationDelegatingHandler>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
//register http services
services.AddHttpClient<IBasketService, BasketService>()
.AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>()
.AddPolicyHandler(GetRetryPolicy())
.AddPolicyHandler(GetCircuitBreakerPolicy());
services.AddHttpClient<ICatalogService, CatalogService>()
.AddPolicyHandler(GetRetryPolicy())
.AddPolicyHandler(GetCircuitBreakerPolicy());
services.AddHttpClient<IOrderApiClient, OrderApiClient>()
.AddPolicyHandler(GetRetryPolicy())
.AddPolicyHandler(GetCircuitBreakerPolicy());
return services;
}
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
}
static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}
}
}