public void ConfigureServices(IServiceCollection services) { services.AddCors(b => b.AddPolicy("AllowAny", p => p .AllowAnyHeader() .AllowAnyMethod() .AllowAnyOrigin() .AllowCredentials() .SetPreflightMaxAge(TimeSpan.FromMinutes(5)) .WithExposedHeaders("ETag", "Link", "X-RateLimit-Limit", "X-RateLimit-Remaining", "X-Result-Count"))); services.Configure <ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; options.RequireHeaderSymmetry = false; }); services.AddMvc(o => { o.Filters.Add(new CorsAuthorizationFilterFactory("AllowAny")); o.Filters.Add <RequireHttpsExceptLocalAttribute>(); o.Filters.Add <ApiExceptionFilter>(); o.ModelBinderProviders.Add(new CustomAttributesModelBinderProvider()); o.InputFormatters.Insert(0, new RawRequestBodyFormatter()); }).AddJsonOptions(o => { o.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Include; o.SerializerSettings.NullValueHandling = NullValueHandling.Include; o.SerializerSettings.Formatting = Formatting.Indented; o.SerializerSettings.ContractResolver = Core.Bootstrapper.GetJsonContractResolver(); // TODO: See if we can resolve this from the di. }); services.AddAuthentication(ApiKeyAuthenticationOptions.ApiKeySchema).AddApiKeyAuthentication(); services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); options.AddPolicy(AuthorizationRoles.ClientPolicy, policy => policy.RequireClaim(ClaimTypes.Role, AuthorizationRoles.Client)); options.AddPolicy(AuthorizationRoles.UserPolicy, policy => policy.RequireClaim(ClaimTypes.Role, AuthorizationRoles.User)); options.AddPolicy(AuthorizationRoles.GlobalAdminPolicy, policy => policy.RequireClaim(ClaimTypes.Role, AuthorizationRoles.GlobalAdmin)); }); services.AddRouting(r => { r.LowercaseUrls = true; r.ConstraintMap.Add("identifier", typeof(IdentifierRouteConstraint)); r.ConstraintMap.Add("identifiers", typeof(IdentifiersRouteConstraint)); r.ConstraintMap.Add("objectid", typeof(ObjectIdRouteConstraint)); r.ConstraintMap.Add("objectids", typeof(ObjectIdsRouteConstraint)); r.ConstraintMap.Add("token", typeof(TokenRouteConstraint)); r.ConstraintMap.Add("tokens", typeof(TokensRouteConstraint)); }); services.AddSwaggerGen(c => { c.SwaggerDoc("v2", new Info { Title = "Exceptionless API", Version = "v2" }); c.AddSecurityDefinition("access_token", new ApiKeyScheme { Name = "access_token", In = "header", Description = "API Key Authentication" }); c.AddSecurityDefinition("basic", new BasicAuthScheme { Description = "Basic HTTP Authentication" }); if (File.Exists($@"{AppDomain.CurrentDomain.BaseDirectory}\Exceptionless.Api.xml")) { c.IncludeXmlComments($@"{AppDomain.CurrentDomain.BaseDirectory}\Exceptionless.Api.xml"); } c.IgnoreObsoleteActions(); }); Bootstrapper.RegisterServices(services, _loggerFactory); services.AddSingleton(new ThrottlingOptions { MaxRequestsForUserIdentifierFunc = userIdentifier => Settings.Current.ApiThrottleLimit, Period = TimeSpan.FromMinutes(15) }); }