// 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 https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.Configure <JwtSettings>(Configuration.GetSection("ApplicationSettings:Jwt")); services.Configure <DesktopIntegrationSettings>(Configuration.GetSection("ApplicationSettings:DesktopIntegration")); services.Configure <ClientDiscoverySettings>(Configuration.GetSection("ApplicationSettings:ServerUrlTransmitter")); services.Configure <StaticFileOptions>(options => { var contentTypeProvider = new FileExtensionContentTypeProvider(); contentTypeProvider.Mappings[".apk"] = "application/vnd.android.package-archive"; options.ContentTypeProvider = contentTypeProvider; }); services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); }); services.AddHttpClient(Constants.UnsafeHttpClientName).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator }); services.AddHealthChecks(); services.AddGrpc(); services.AddDatabaseDeveloperPageExceptionFilter(); services.AddOptions(); services.AddAuthorization(options => { options.AddPolicy(PolicyNames.ApplicationPermissionPolicy, policyBuilder => { policyBuilder.AddAuthenticationSchemes( CookieAuthenticationDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() .AddRequirements(new HostCommandPermissionRequirement()) .Build(); }); options.AddPolicy(PolicyNames.ApiPolicy, policyBuilder => { policyBuilder.AddAuthenticationSchemes( CookieAuthenticationDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() .Build(); }); }); services.AddDbContext <ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); var tokenValidationParameters = new TokenValidationParameters(); tokenValidationParameters.ValidateIssuer = true; tokenValidationParameters.ValidateAudience = true; tokenValidationParameters.ValidateLifetime = true; tokenValidationParameters.ValidateIssuerSigningKey = true; tokenValidationParameters.ValidIssuer = Configuration["ApplicationSettings:Jwt:Issuer"]; tokenValidationParameters.ValidAudience = Configuration["ApplicationSettings:Jwt:Issuer"]; tokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["ApplicationSettings:Jwt:Key"])); services.AddSingleton(tokenValidationParameters); services .AddAuthentication(); services .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => { options.SaveToken = true; options.RefreshInterval = TimeSpan.Parse(Configuration["ApplicationSettings:Jwt:RefreshAccessTokenInterval"]); options.TokenValidationParameters = tokenValidationParameters; options.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { context.Response.Headers.Add("X-Token-Expired", "true"); } return(Task.CompletedTask); } }; }); services.AddDefaultIdentity <ApplicationUser>(options => { options.Password.RequireDigit = false; options.Password.RequireLowercase = false; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequiredLength = 3; options.Password.RequiredUniqueChars = 1; options.SignIn.RequireConfirmedAccount = true; }) .AddDefaultTokenProviders() .AddUserManager <UserManager <ApplicationUser> >() .AddRoles <IdentityRole>() .AddEntityFrameworkStores <ApplicationDbContext>(); services.AddHttpContextAccessor(); services.AddHttpClient("local", (provider, client) => { var accessor = provider.GetRequiredService <IHttpContextAccessor>(); client.BaseAddress = new Uri($"https://localhost:{accessor.HttpContext.Connection.LocalPort}"); }); services.AddControllers(); services.AddRazorPages(); services.AddServerSideBlazor(); ServiceRegistrar.Register(services); }