public void ConfigureServices()

in Backend/src/Trackable.Web/Startup.cs [38:179]


        public void ConfigureServices(IServiceCollection services)
        {
            // Cors
            services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
                                                                            .AllowAnyMethod()
                                                                            .AllowAnyHeader()
                                                                            .AllowCredentials()
                                                                            .Build()));
            // Security Key for Jwt
            var jwtKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authorization:SecurityKey"]));
            services.AddSingleton(new SigningCredentials(jwtKey, SecurityAlgorithms.HmacSha256));

            // Cookie based OpenId Authentication + Jwt Auth for programmatic Apis
            // Use JwtBearer as default to stop automatic redirect
            services
                .AddAuthentication(cfg =>
                {
                    cfg.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                    cfg.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    cfg.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                })
                .AddCookie(cookieopt =>
                {
                    cookieopt.Events.OnRedirectToAccessDenied = context =>
                    {
                        context.Response.StatusCode = 403;
                        return Task.CompletedTask;
                    };
                    cookieopt.Events.OnRedirectToLogin = DoNotRedirectApiCalls;
                })
                .AddOpenIdConnect(options =>
                {
                    options.ClientId = Configuration["Authorization:ClientId"];
                    options.ClientSecret = Configuration["Authorization:ClientSecret"];
                    options.Authority = Configuration["Authorization:Authority"];
                    options.ResponseType = OpenIdConnectResponseType.IdToken;
                    options.CallbackPath = "/signin-oidc";
                    options.Events = new OpenIdConnectEvents
                    {
                        OnRemoteFailure = OnAuthenticationFailed,
                        OnRedirectToIdentityProvider = DoNotRedirectApiCalls,
                    };
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidateIssuer = false
                    };
                })
                .AddJwtBearer(jwtBearerOptions =>
                {
                    jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = jwtKey,
                        ValidateIssuer = true,
                        ValidIssuer = JwtAuthConstants.Issuer,
                        ValidateAudience = true,
                        ValidAudiences = new[] { JwtAuthConstants.DeviceAudience, JwtAuthConstants.UserAudience, JwtAuthConstants.RegistrationAudience },
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.FromMinutes(5),
                    };
                });

            // Authorization
            services
                .AddAuthorization(options =>
                {
                    options.AddPolicy(UserRoles.Blocked, policy => policy.Requirements.Add(new RoleRequirement(UserRoles.Blocked)));
                    options.AddPolicy(UserRoles.Pending, policy => policy.Requirements.Add(new RoleRequirement(UserRoles.Pending)));
                    options.AddPolicy(UserRoles.DeviceRegistration, policy => policy.Requirements.Add(new RoleRequirement(UserRoles.DeviceRegistration)));
                    options.AddPolicy(UserRoles.TrackingDevice, policy => policy.Requirements.Add(new RoleRequirement(UserRoles.TrackingDevice)));
                    options.AddPolicy(UserRoles.Viewer, policy => policy.Requirements.Add(new RoleRequirement(UserRoles.Viewer)));
                    options.AddPolicy(UserRoles.Administrator, policy => policy.Requirements.Add(new RoleRequirement(UserRoles.Administrator)));
                    options.AddPolicy(UserRoles.Owner, policy => policy.Requirements.Add(new RoleRequirement(UserRoles.Owner)));
                });

            // Business Logic Services
            services.AddServices(
                    Configuration.GetConnectionString("DefaultConnection"),
                    Environment.WebRootPath)
                .AddTransient<IAuthorizationHandler, RoleRequirementHandler>()
                .AddScoped<ExceptionHandlerFilter>()
                .AddTripDetection(Configuration["SubscriptionKeys:BingMaps"])
                .AddSingleton<IHostedService, HostedInstrumentationService>()
                .AddSingleton<Profile, DtoMappingProfile>();

            // Add AutoMapper profiles
            var mapperConfiguration = new MapperConfiguration(cfg =>
            {
                foreach (var mapperProfile in services.Where(s => s.ServiceType == typeof(AutoMapper.Profile)))
                {
                    var type = mapperProfile.ImplementationType;
                    cfg.AddProfile(type);
                }
            });
            mapperConfiguration.CompileMappings();
            services.AddScoped<IMapper>(ctx => new Mapper(mapperConfiguration, t => ctx.GetService(t)));

            if (Configuration.GetValue<bool>("Serving:ServeSwagger"))
            {
                // Register the Swagger generator, defining one or more Swagger documents
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new()
                    {
                        Title = "BMFT APIs",
                        Version = "v1",
                        Description = "Bing Maps Fleet Tracker is an open source fleet tracking solution. Read more at https://github.com/Microsoft/Bing-Maps-Fleet-Tracker",
                        License = new OpenApiLicense { Name = "MIT Licencse", Url = new Uri("https://github.com/Microsoft/Bing-Maps-Fleet-Tracker/blob/master/LICENSE") }
                    });

                    c.DescribeAllParametersInCamelCase();
                    c.DocInclusionPredicate((version, description) =>
                    {
                        return description.RelativePath.StartsWith("api");
                    });

                    var filePath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Trackable.Web.xml");
                    c.IncludeXmlComments(filePath);
                });
            }

            // Add MVC
            services
                .AddMvc(options =>
                {
                    // Add Exception Handler
                    options.Filters.Add(typeof(ExceptionHandlerFilter));

                    // Add Https require filter if not running locally
                    if (!Configuration.GetValue<bool>("Serving:IsDebug"))
                    {
                        options.Filters.Add(new RequireHttpsAttribute());
                    }
                });

            // Add socket management
            services
                .AddSignalR();

            services
                .AddApplicationInsightsTelemetry(Configuration.GetConnectionString("ApplicationInsights"));
        }