using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.Linq; using System.Net; using System.Threading; using WebhookClient.Services; namespace WebhookClient { 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.AddSession(opt => { opt.Cookie.Name = ".eShopWebhooks.Session"; }) .AddConfiguration(Configuration) .AddHttpClientServices(Configuration) .AddCustomAuthentication(Configuration) .AddTransient() .AddSingleton() .AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_3_0); services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { var pathBase = Configuration["PATH_BASE"]; if (!string.IsNullOrEmpty(pathBase)) { app.UsePathBase(pathBase); } if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. } app.UseAuthentication(); app.Map("/check", capp => { capp.Run(async (context) => { if ("OPTIONS".Equals(context.Request.Method, StringComparison.InvariantCultureIgnoreCase)) { var validateToken = bool.TrueString.Equals(Configuration["ValidateToken"], StringComparison.InvariantCultureIgnoreCase); var header = context.Request.Headers[HeaderNames.WebHookCheckHeader]; var value = header.FirstOrDefault(); var tokenToValidate = Configuration["Token"]; if (!validateToken || value == tokenToValidate) { if (!string.IsNullOrWhiteSpace(tokenToValidate)) { context.Response.Headers.Add(HeaderNames.WebHookCheckHeader, tokenToValidate); } context.Response.StatusCode = (int)HttpStatusCode.OK; } else { await context.Response.WriteAsync("Invalid token"); context.Response.StatusCode = (int)HttpStatusCode.BadRequest; } } else { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; } }); }); app.UseStaticFiles(); app.UseSession(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); }); } } static class ServiceExtensions { public static IServiceCollection AddConfiguration(this IServiceCollection services, IConfiguration configuration) { services.AddOptions(); services.Configure(configuration); return services; } public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) { var identityUrl = configuration.GetValue("IdentityUrl"); var callBackUrl = configuration.GetValue("CallBackUrl"); // Add Authentication services services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie(setup => setup.ExpireTimeSpan = TimeSpan.FromHours(2)) .AddOpenIdConnect(options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.Authority = identityUrl.ToString(); options.SignedOutRedirectUri = callBackUrl.ToString(); options.ClientId = "webhooksclient"; options.ClientSecret = "secret"; options.ResponseType = "code id_token"; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; options.RequireHttpsMetadata = false; options.Scope.Add("openid"); options.Scope.Add("webhooks"); }); return services; } public static IServiceCollection AddHttpClientServices(this IServiceCollection services, IConfiguration configuration) { services.AddSingleton(); services.AddTransient(); services.AddHttpClient("extendedhandlerlifetime").SetHandlerLifetime(Timeout.InfiniteTimeSpan); //add http client services services.AddHttpClient("GrantClient") .SetHandlerLifetime(TimeSpan.FromMinutes(5)) .AddHttpMessageHandler(); return services; } } }