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"));
}