// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers() .AddControllersAsServices() // Adding option to ignore Null values when sending back JsonResult from any Web Api //.AddJsonOptions(options => //{ // options.JsonSerializerOptions.IgnoreNullValues = true; // options.JsonSerializerOptions.WriteIndented = true; // optin //}) // Adding this option to be able to send back JObjet from any Web Api .AddNewtonsoftJson(options => { options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; options.SerializerSettings.Formatting = Formatting.Indented; options.SerializerSettings.Converters.Add(new StringEnumConverter()); }); services.AddHttpClient(); services.AddHttpContextAccessor(); services.AddOptions(); services.AddDistributedMemoryCache(); services.Configure <CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; // consent required options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddSession(option => { option.IdleTimeout = TimeSpan.FromMinutes(45); option.Cookie.IsEssential = true; }); services.Configure <YGraphOptions>(options => Configuration.Bind("Graph", options)); services.Configure <YHostOptions>(options => Configuration.Bind("YgdraServices", options)); services.Configure <YMicrosoftIdentityOptions>(options => Configuration.Bind("AzureAD", options)); // Need an instance to get the scopes... var graphOptions = new YGraphOptions(); Configuration.Bind("Graph", graphOptions); services.AddMicrosoftIdentityWebAppAuthentication(Configuration) .EnableTokenAcquisitionToCallDownstreamApi(graphOptions.GetScopes()) .AddSessionTokenCaches(); services.AddScoped <IYAuthProvider, YAuthProvider>(); services.AddScoped <IYHttpRequestHandler, YHttpRequestHandler>(); services.AddScoped <IYResourceClient, YResourceClient>(); services.AddMicrosoftGraph(Configuration); //services.AddControllersWithViews().AddMicrosoftIdentityUI(); services.AddControllersWithViews(); services.AddRazorPages() .AddMvcOptions(options => { options.ModelBinderProviders.Insert(0, new PolymorphicEntitySourceBinderProvider()); options.ModelBinderProviders.Insert(0, new PolymorphicDataSourceViewModelBinderProvider()); var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); options.Filters.Add(new AuthorizeFilter(policy)); }).AddMicrosoftIdentityUI(); services.AddControllers(); var signalROptions = new YSignalROptions(); Configuration.Bind("SignalR", signalROptions); services.AddSignalR().AddAzureSignalR(options => { options.ConnectionString = signalROptions.ConnectionString; options.ServerStickyMode = ServerStickyMode.Required; }); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { IdentityModelEventSource.ShowPII = true; services.AddControllers() .AddControllersAsServices() // Adding this option to be able to send back JObjet from any Web Api .AddNewtonsoftJson(options => { options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; options.SerializerSettings.Formatting = Formatting.Indented; options.SerializerSettings.Converters.Add(new StringEnumConverter()); }); // Allow Any origin services.AddCors(options => options.AddDefaultPolicy(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader())); services.Configure <YGraphOptions>(options => Configuration.Bind("Graph", options)); services.Configure <YProviderOptions>(options => Configuration.Bind("YProvider", options)); services.Configure <YHostOptions>(options => Configuration.Bind("YgdraServices", options)); services.Configure <YMicrosoftIdentityOptions>(options => Configuration.Bind("AzureAD", options)); var hangFireOptions = new YProviderOptions(); Configuration.Bind("HangFire", hangFireOptions); services.AddHangfire(x => x.UseAzureCosmosDbStorage(hangFireOptions.Endpoint, hangFireOptions.AccountKey, hangFireOptions.Database, hangFireOptions.Container)); services.AddHangfireServer(); // For Production deployment services.AddMicrosoftIdentityWebApiAuthentication(Configuration) .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches(); // ----------------------------------------------------------------------------------- // For dev only (Because Microsoft does not authorize to add API without admin consent) // Override Token Validation Parameters services.AddOptions <JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme) .Configure(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, //ValidateIssuerSigningKey = false, //ValidateActor = false, }; // Be sure we have events options.Events ??= new JwtBearerEvents(); // Get already handler on Validation to be able to call it var onTokenValidatedHandler = options.Events.OnTokenValidated; // Create a new one options.Events.OnTokenValidated = async context => { // Because we can't consent the scope of the web api (MS tenant does not authorize it) // We don't validated neither scope neither roles await Task.CompletedTask; // If we can have an admin consent on application consent for web url, we may want to // test it again here //await onTokenValidatedHandler(context).ConfigureAwait(false); }; var onAuthenticationFailedHandler = options.Events.OnAuthenticationFailed; options.Events.OnAuthenticationFailed = async context => { Console.WriteLine("OnAuthenticationFailed: " + context.Exception.Message); await onAuthenticationFailedHandler(context).ConfigureAwait(false); }; }); services.AddYProvider(Configuration); services.AddHttpClient(); services.AddHttpContextAccessor(); services.AddScoped <IYAuthProvider, YAuthProvider>(); services.AddScoped <IYHttpRequestHandler, YHttpRequestHandler>(); services.AddScoped <IYResourceClient, YResourceClient>(); services.AddScoped <IYNotificationsService, YNotificationsService>(); services.AddScoped <IYEnginesService, YEnginesService>(); services.AddScoped <IYHangFireService, YHangFireService>(); services.AddScoped <IYDataSourcesService, YDataSourcesService>(); // Configure Swagger correctly to add an authorization button and inject bearer token to all needed calls services.AddAzureOauth2Swagger(Configuration); var signalROptions = new YSignalROptions(); Configuration.Bind("SignalR", signalROptions); var serviceManager = new ServiceManagerBuilder().WithOptions(option => { option.ConnectionString = signalROptions.ConnectionString; option.ServiceTransportType = ServiceTransportType.Persistent; }).Build(); services.AddSingleton(serviceManager); services.AddSignalR().AddAzureSignalR(options => { options.ConnectionString = signalROptions.ConnectionString; }); }