// 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) { _appConfig.ConfigureIdentitySearchProviderServiceUrl(); var identityServerApiSettings = _appConfig.IdentityServerConfidentialClientSettings; services.TryAddSingleton(_appConfig.HostingOptions); services.TryAddSingleton <IConnectionStrings>(_appConfig.ConnectionStrings); var hostingOptions = services.BuildServiceProvider().GetRequiredService <HostingOptions>(); var connectionStrings = services.BuildServiceProvider().GetRequiredService <IConnectionStrings>(); var eventLogger = LogFactory.CreateEventLogger(_loggingLevelSwitch, hostingOptions, connectionStrings); var serilogEventSink = new SerilogEventSink(eventLogger); var settings = _appConfig.IdentityServerConfidentialClientSettings; var tokenUriAddress = $"{settings.Authority.EnsureTrailingSlash()}connect/token"; services.AddTransient <IHttpRequestMessageFactory>(serviceProvider => new HttpRequestMessageFactory( tokenUriAddress, FabricIdentityConstants.FabricIdentityClient, settings.ClientSecret, null, null)); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>() .AddSingleton <HttpClient>() .AddSingleton <IEventSink>(serilogEventSink) .AddSingleton(_appConfig) .AddSingleton(_logger) .AddIdentityServer(_appConfig, _certificateService, _logger, hostingOptions, connectionStrings) .AddAuthorizationServices() .AddScoped <IUserResolverService, UserResolverService>() .AddSingleton <ISerializationSettings, SerializationSettings>() .AddSingleton <ILdapConnectionProvider, LdapConnectionProvider>() .AddSingleton <IExternalIdentityProviderServiceResolver, ExternalIdentityProviderServiceResolver>() .AddSingleton <IExternalIdentityProviderService, IdPSearchServiceProvider>() .AddSingleton <LdapProviderService>() .AddSingleton <PolicyProvider>() .AddSingleton <IHealthCheckerService, HealthCheckerService>() .AddFluentValidations(); // filter settings var filterSettings = _appConfig.FilterSettings ?? new FilterSettings { GroupFilterSettings = new GroupFilterSettings() }; filterSettings.GroupFilterSettings = filterSettings.GroupFilterSettings ?? new GroupFilterSettings(); services.TryAddSingleton(filterSettings.GroupFilterSettings); services.AddSingleton <GroupFilterService>(); services.TryAddSingleton(_appConfig.LdapSettings); services.TryAddSingleton(new IdentityServerAuthenticationOptions { Authority = identityServerApiSettings.Authority, RequireHttpsMetadata = false, ApiName = identityServerApiSettings.ClientId }); services.AddTransient <IIdentityProviderConfigurationService, IdentityProviderConfigurationService>(); services.AddTransient <AccountService>(); services.AddMvc(options => { options.Conventions.Add(new CommaSeparatedQueryStringConvention()); }) .AddJsonOptions(x => { x.SerializerSettings.ReferenceLoopHandling = new SerializationSettings().JsonSettings.ReferenceLoopHandling; }); services.AddApiVersioning(options => { options.AssumeDefaultVersionWhenUnspecified = true; options.DefaultApiVersion = new ApiVersion(1, 0); options.ReportApiVersions = true; }); // Swagger services.AddSwaggerGen(c => { // this defines the Swagger doc (1 call to SwaggerDoc per version) c.SwaggerDoc("v1", new Info { Version = "v1", Title = "Health Catalyst Fabric Identity API V1", Description = "Fabric.Identity contains a set of APIs that provides authentication for applications based on the OpenID Connect protocol. If you don't include the version in the URL you will get the v1 API." }); c.DocInclusionPredicate((docName, apiDesc) => { var versions = apiDesc.ControllerAttributes() .OfType <ApiVersionAttribute>() .SelectMany(attr => attr.Versions); return(versions.Any(v => $"v{v.ToString().Substring(0, 1)}" == docName)); }); c.AddSecurityDefinition("oauth2", new OAuth2Scheme { Description = "The Fabric.Identity management API requires authentication using oath2 and requires the below scopes.", Type = "oauth2", AuthorizationUrl = identityServerApiSettings.Authority, Flow = "hybrid, implicit, client_credentials", Scopes = new Dictionary <string, string> { { "fabric/identity.manageresources", "Access to manage Client, API, and Identity resources." } } }); c.CustomSchemaIds(type => type.FullName); c.OperationFilter <VersionRemovalOperationFilter>(); c.OperationFilter <ParamMetadataOperationFilter>(); c.OperationFilter <SecurityRequirementsOperationFilter>(); c.OperationFilter <SetBodyParametersRequiredOperationFilter>(); c.DocumentFilter <PathVersionDocumentFilter>(); c.DocumentFilter <TagFilter>(); c.IncludeXmlComments(XmlCommentsFilePath); c.DescribeAllEnumsAsStrings(); }); }
// 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) { if (_appConfig.ApplicationInsights?.Enabled ?? false) { services.AddApplicationInsightsTelemetry(); } var identityServerApiSettings = _appConfig.IdentityServerConfidentialClientSettings; services.TryAddSingleton(_appConfig.HostingOptions); services.TryAddSingleton <IConnectionStrings>(_appConfig.ConnectionStrings); var hostingOptions = services.BuildServiceProvider().GetRequiredService <HostingOptions>(); var connectionStrings = services.BuildServiceProvider().GetRequiredService <IConnectionStrings>(); var eventLogger = LogFactory.CreateEventLogger(hostingOptions, connectionStrings); var serilogEventSink = new SerilogEventSink(eventLogger); var settings = _appConfig.IdentityServerConfidentialClientSettings; var tokenUriAddress = $"{settings.Authority.EnsureTrailingSlash()}connect/token"; services.AddTransient <IHttpRequestMessageFactory>(serviceProvider => new HttpRequestMessageFactory( tokenUriAddress, FabricIdentityConstants.FabricIdentityClient, settings.ClientSecret, null, null)); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>() .AddSingleton <HttpClient>() .AddSingleton <IEventSink>(serilogEventSink) .AddSingleton(_appConfig) .AddSingleton(Log.Logger) .AddIdentityServer(_appConfig, _certificateService, Log.Logger, hostingOptions, connectionStrings) .AddAuthorizationServices() .AddPrincipalSearchServices(_appConfig) .AddScoped <IUserResolverService, UserResolverService>() .AddSingleton <ISerializationSettings, SerializationSettings>() .AddSingleton <ILdapConnectionProvider, LdapConnectionProvider>() .AddSingleton <IExternalIdentityProviderServiceResolver, ExternalIdentityProviderServiceResolver>() .AddSingleton <IExternalIdentityProviderService, IdPSearchServiceProvider>() .AddSingleton <Services.IClaimsService, ClaimsService>() .AddSingleton <LdapProviderService>() .AddSingleton <PolicyProvider>() .AddTransient <IHealthCheckerService, HealthCheckerService>() .AddTransient <ICorsPolicyProvider, DefaultCorsPolicyProvider>() .AddLocalization(opts => { opts.ResourcesPath = "Resources"; }) .AddFluentValidations(); var mapperConfig = new MapperConfiguration(cfg => { cfg.AddProfile(new MapperProfile()); }); IMapper mapper = mapperConfig.CreateMapper(); services.AddSingleton(mapper); // filter settings var filterSettings = _appConfig.FilterSettings ?? new FilterSettings { GroupFilterSettings = new GroupFilterSettings() }; filterSettings.GroupFilterSettings = filterSettings.GroupFilterSettings ?? new GroupFilterSettings(); services.TryAddSingleton(filterSettings.GroupFilterSettings); services.AddSingleton <GroupFilterService>(); services.TryAddSingleton(_appConfig.LdapSettings); services.TryAddSingleton(new IdentityServerAuthenticationOptions { Authority = identityServerApiSettings.Authority, RequireHttpsMetadata = false, ApiName = identityServerApiSettings.ClientId }); services.AddAuthentication().AddJwtBearer(o => { o.Authority = identityServerApiSettings.Authority; o.Audience = identityServerApiSettings.ClientId; o.RequireHttpsMetadata = false; }).AddAzureIdentityProviderIfApplicable(_appConfig).AddExternalIdentityProviders(_appConfig); services.AddTransient <IIdentityProviderConfigurationService, IdentityProviderConfigurationService>(); services.AddTransient <AccountService>(); services.Configure <CookiePolicyOptions>(options => { options.OnAppendCookie = cookie => { var isIdentityServerCookie = cookie.CookieName.Equals(IdentityServerConstants.DefaultCheckSessionCookieName) || cookie.CookieName.Equals(IdentityServerConstants.DefaultCookieAuthenticationScheme) || cookie.CookieName.Equals(IdentityServerConstants.ExternalCookieAuthenticationScheme); if (isIdentityServerCookie && cookie.Context.Request.IsHttps) { cookie.CookieOptions.SameSite = SameSiteMode.None; cookie.CookieOptions.Secure = true; } }; options.OnDeleteCookie = cookie => { var isIdentityServerCookie = cookie.CookieName.Equals(IdentityServerConstants.DefaultCheckSessionCookieName) || cookie.CookieName.Equals(IdentityServerConstants.DefaultCookieAuthenticationScheme) || cookie.CookieName.Equals(IdentityServerConstants.ExternalCookieAuthenticationScheme); if (isIdentityServerCookie && cookie.Context.Request.IsHttps) { cookie.CookieOptions.SameSite = SameSiteMode.None; cookie.CookieOptions.Secure = true; } }; }); services.AddMvc(options => { options.Conventions.Add(new CommaSeparatedQueryStringConvention()); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddJsonOptions(x => { x.SerializerSettings.ReferenceLoopHandling = new SerializationSettings().JsonSettings.ReferenceLoopHandling; }); services.AddApiVersioning(options => { options.AssumeDefaultVersionWhenUnspecified = true; options.DefaultApiVersion = new ApiVersion(1, 0); options.ReportApiVersions = true; }); // Swagger services.AddSwaggerGen(c => { // this defines the Swagger doc (1 call to SwaggerDoc per version) c.SwaggerDoc("v1", new Info { Version = "v1", Title = "Health Catalyst Fabric Identity API V1", Description = "Fabric.Identity contains a set of APIs that provides authentication for applications based on the OpenID Connect protocol. If you don't include the version in the URL you will get the v1 API." }); c.DocInclusionPredicate((docName, apiDesc) => { if (!apiDesc.TryGetMethodInfo(out var methodInfo)) { return(false); } var versions = methodInfo.DeclaringType .GetCustomAttributes(true) .OfType <ApiVersionAttribute>() .SelectMany(attr => attr.Versions); return(versions.Any(v => $"v{v.ToString().Substring(0, 1)}" == docName)); }); c.AddSecurityDefinition("oauth2", new OAuth2Scheme { Description = "The Fabric.Identity management API requires authentication using oath2 and requires the below scopes.", Type = "oauth2", AuthorizationUrl = identityServerApiSettings.Authority, Flow = "hybrid, implicit, client_credentials", Scopes = new Dictionary <string, string> { { "fabric/identity.manageresources", "Access to manage Client, API, and Identity resources." } } }); c.CustomSchemaIds(type => type.FullName); c.OperationFilter <VersionRemovalOperationFilter>(); c.OperationFilter <ParamMetadataOperationFilter>(); c.OperationFilter <SecurityRequirementsOperationFilter>(); c.OperationFilter <SetBodyParametersRequiredOperationFilter>(); c.DocumentFilter <PathVersionDocumentFilter>(); c.DocumentFilter <TagFilter>(); c.IncludeXmlComments(XmlCommentsFilePath); c.DescribeAllEnumsAsStrings(); }); }