Advertisement
DenysKashkovskyi

ASP.NET Core 3.0 Startup

Oct 16th, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.34 KB | None | 0 0
  1. using System;
  2. using System.Net;
  3. using System.Reflection;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Autofac;
  7. using Autofac.Extensions.DependencyInjection;
  8. using AutoMapper;
  9. using Core;
  10. using Core.BackgroundJobs;
  11. using Core.Domain.Entities;
  12. using Core.Interfaces;
  13. using Infrastructure;
  14. using Infrastructure.Auth;
  15. using Infrastructure.Data;
  16. using Infrastructure.Helpers;
  17. using Microsoft.AspNetCore.Authentication.JwtBearer;
  18. using Microsoft.AspNetCore.Builder;
  19. using Microsoft.AspNetCore.Diagnostics;
  20. using Microsoft.AspNetCore.Hosting;
  21. using Microsoft.AspNetCore.Http;
  22. using Microsoft.AspNetCore.Http.Features;
  23. using Microsoft.AspNetCore.Identity;
  24. using Microsoft.AspNetCore.Mvc;
  25. using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
  26. using Microsoft.EntityFrameworkCore;
  27. using Microsoft.Extensions.Configuration;
  28. using Microsoft.Extensions.DependencyInjection;
  29. using Microsoft.Extensions.Hosting;
  30. using Microsoft.IdentityModel.Tokens;
  31. using Swashbuckle.AspNetCore.Swagger;
  32. using Web.Extensions;
  33. using Web.Hubs;
  34. using Web.Models.Settings;
  35. using Web.Service;
  36. using Web.Utils;
  37.  
  38. namespace Legal
  39. {
  40.     public class Startup
  41.     {
  42.         public IConfiguration Configuration { get; }
  43.         public IWebHostEnvironment Env { get; }
  44.         public Startup(IConfiguration configuration, IWebHostEnvironment env) => (Configuration, Env) = (configuration, env);
  45.         public IServiceProvider ConfigureServices(IServiceCollection services)
  46.         {
  47.             ConfigureContext(services);
  48.             var appSettings = ConfigureAppSettings(services);
  49.             ConfigureAuth(services, appSettings);
  50.             ConfigureWeb(services);
  51.             ConfigureBackgroundJobs(services);
  52.             ConfigureSwagger(services);
  53.             return ConfigureContainer(services, appSettings);
  54.         }
  55.  
  56.         public void Configure(
  57.             IApplicationBuilder app,
  58.             IWebHostEnvironment env,
  59.             UserManager<User> userManager,
  60.             RoleManager<Role> roleManager)
  61.         {
  62.             app.UseExceptionHandler(
  63.                 builder =>
  64.                 {
  65.                     builder.Run(
  66.                         async context =>
  67.                         {
  68.                             context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
  69.                             context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
  70.  
  71.                             var error = context.Features.Get<IExceptionHandlerFeature>();
  72.                             if (error != null)
  73.                             {
  74.                                 context.Response.AddApplicationError(error.Error.Message);
  75.                                 await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false);
  76.                             }
  77.                         });
  78.                 });
  79.  
  80.             if (env.IsDevelopment())
  81.             {
  82.                 app.UseSwagger();
  83.                 app.UseSwaggerUI(c =>
  84.                 {
  85.                     c.SwaggerEndpoint("v1/swagger.json", "LegalAPI v1");
  86.                 });
  87.             }
  88.             else
  89.             {
  90.                 app.UseHsts();
  91.             }
  92.  
  93.             if (env.IsProduction())
  94.             {
  95.                 app.UseHttpsRedirection();
  96.             }
  97.  
  98.             app.UseAuthorization();
  99.             app.UseAuthentication();
  100.  
  101.             app.UseResponseCompression();
  102.  
  103.             var webSocketOptions = new WebSocketOptions()
  104.             {
  105.                 KeepAliveInterval = TimeSpan.FromSeconds(120),
  106.                     ReceiveBufferSize = 4 * 1024
  107.             };
  108.  
  109.             app.UseWebSockets(webSocketOptions);
  110.  
  111.             app.UseFileServer();
  112.             app.UseSpaStaticFiles();
  113.             app.UseRouting();
  114.  
  115.             // IdentityDataInitializer.SeedData(userManager, roleManager);
  116.  
  117.             app.UseEndpoints(routes =>
  118.             {
  119.                 routes.MapControllerRoute(
  120.                     name: "default",
  121.                     pattern: "{controller}/{action=Index}/{id?}");
  122.                 routes.MapHub<NotificationHub>("/hub/notification");
  123.             });
  124.  
  125.             app.UseSpa(spa =>
  126.             {
  127.                 spa.Options.SourcePath = "wwwroot";
  128.  
  129.                 if (env.IsDevelopment())
  130.                 {
  131.                     spa.UseReactDevelopmentServer(npmScript: "start");
  132.                 }
  133.             });
  134.         }
  135.  
  136.         private void ConfigureContext(IServiceCollection services)
  137.         {
  138.             services.AddDbContextPool<AppDbContext>(options =>
  139.                 options.UseSqlServer(Configuration["TestConnection"],
  140.                     b =>
  141.                     {
  142.                         b.MigrationsAssembly("Infrastructure");
  143.                         b.EnableRetryOnFailure();
  144.                     }));
  145.             services.AddIdentity<User, Role>(o =>
  146.             {
  147.                 o.Stores.MaxLengthForKeys = 128;
  148.                 o.Password.RequireDigit = false;
  149.                 o.Password.RequireLowercase = false;
  150.                 o.Password.RequireUppercase = false;
  151.                 o.Password.RequireNonAlphanumeric = false;
  152.                 o.Password.RequiredLength = 6;
  153.             }).AddEntityFrameworkStores<AppDbContext>().AddDefaultTokenProviders();
  154.         }
  155.  
  156.         private AppSettings ConfigureAppSettings(IServiceCollection services)
  157.         {
  158.             var appSettings = new AppSettings
  159.             {
  160.                 SecretKey = Configuration["JwtKey"],
  161.                     SendGridApiKey = Configuration["SendGridApiKey"],
  162.                     EmailSenderAddress = Configuration["EmailSenderAddress"],
  163.                     EmailSenderName = Configuration["EmailSenderName"],
  164.                     Country = Configuration["Legal:Country"],
  165.                     BaseUrl = Configuration["BaseUrl"],
  166.                     SupportEmail = Configuration["SupportEmail"]
  167.             };
  168.             services.AddSingleton(appSettings);
  169.             return appSettings;
  170.         }
  171.  
  172.         private void ConfigureAuth(IServiceCollection services, AppSettings appSettings)
  173.         {
  174.             var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(appSettings.SecretKey));
  175.  
  176.             var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
  177.  
  178.             services.Configure<JwtIssuerOptions>(options =>
  179.             {
  180.                 options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
  181.                 options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
  182.                 options.SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
  183.             });
  184.  
  185.             var tokenValidationParameters = new TokenValidationParameters
  186.             {
  187.                 ValidateIssuer = true,
  188.                     ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
  189.  
  190.                     ValidateAudience = true,
  191.                     ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
  192.  
  193.                     ValidateIssuerSigningKey = true,
  194.                     IssuerSigningKey = signingKey,
  195.  
  196.                     RequireExpirationTime = false,
  197.                     ValidateLifetime = true,
  198.                     ClockSkew = TimeSpan.Zero
  199.             };
  200.  
  201.             services.AddAuthentication(options =>
  202.             {
  203.                 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  204.                 options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  205.  
  206.             }).AddJwtBearer(configureOptions =>
  207.             {
  208.                 configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
  209.                 configureOptions.TokenValidationParameters = tokenValidationParameters;
  210.                 configureOptions.SaveToken = true;
  211.  
  212.                 configureOptions.Events = new JwtBearerEvents
  213.                 {
  214.                     OnMessageReceived = context =>
  215.                         {
  216.                             var accessToken = context.Request.Query["access_token"];
  217.  
  218.                             var path = context.HttpContext.Request.Path;
  219.                             if (!string.IsNullOrEmpty(accessToken) &&
  220.                                 (path.StartsWithSegments("/hub")))
  221.                             {
  222.                                 context.Token = accessToken;
  223.                             }
  224.                             return Task.CompletedTask;
  225.                         },
  226.                         OnAuthenticationFailed = context =>
  227.                         {
  228.                             if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
  229.                             {
  230.                                 context.Response.Headers.Add("Token-Expired", "true");
  231.                             }
  232.                             return Task.CompletedTask;
  233.                         }
  234.                 };
  235.             });
  236.  
  237.             services.AddAuthorization(options =>
  238.             {
  239.                 options.AddPolicy("EmailConfirmed", policy => policy.RequireClaim(Constants.Strings.JwtClaims.EmailConfirmed, "true"));
  240.             });
  241.         }
  242.  
  243.         private void ConfigureWeb(IServiceCollection services)
  244.         {
  245.             if (Env.IsProduction())
  246.             {
  247.                 services.AddHsts(options =>
  248.                 {
  249.                     options.Preload = true;
  250.                     options.IncludeSubDomains = true;
  251.                     options.MaxAge = TimeSpan.FromDays(60);
  252.                 });
  253.  
  254.                 services.AddHttpsRedirection(options =>
  255.                 {
  256.                     options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
  257.                 });
  258.             }
  259.  
  260.             services.AddMemoryCache();
  261.             services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
  262.  
  263.             services.AddSignalR();
  264.             services.AddMvc()
  265.                 .SetCompatibilityVersion(CompatibilityVersion.Latest);
  266.                 .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<Startup>());
  267.  
  268.             services.Configure<FormOptions>(x =>
  269.             {
  270.                 x.ValueLengthLimit = int.MaxValue;
  271.                 x.MultipartBodyLengthLimit = int.MaxValue;
  272.             });
  273.             services.AddSpaStaticFiles(configuration =>
  274.             {
  275.                 configuration.RootPath = "wwwroot/build";
  276.             });
  277.  
  278.             services.AddResponseCompression();
  279.         }
  280.  
  281.         private void ConfigureSwagger(IServiceCollection services)
  282.         {
  283.             services.AddSwaggerGen(c =>
  284.             {
  285.                 c.SwaggerDoc("v1", new Info { Title = "LegalAPI", Version = "v1" });
  286.             });
  287.         }
  288.  
  289.         private AutofacServiceProvider ConfigureContainer(IServiceCollection services, AppSettings appSettings)
  290.         {
  291.             services.AddScoped<IRazorViewToStringRenderer, RazorViewToStringRenderer>();
  292.             var builder = new ContainerBuilder();
  293.             builder.RegisterInstance(appSettings).As<IAppSettings>().SingleInstance();
  294.             builder.RegisterModule(new CoreModule());
  295.             builder.RegisterModule(new InfrastructureModule());
  296.             builder.RegisterType<ConnectionManager>().As<ConnectionManager>().InstancePerLifetimeScope();
  297.             builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Presenter")).SingleInstance();
  298.             builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Service")).InstancePerLifetimeScope();
  299.  
  300.             builder.Populate(services);
  301.             var container = builder.Build();
  302.             return new AutofacServiceProvider(container);
  303.         }
  304.  
  305.         private void ConfigureBackgroundJobs(IServiceCollection services)
  306.         {
  307.             services.AddHostedService<QueuedHostedService>();
  308.             services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
  309.         }
  310.     }
  311. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement