public void Configure(IApplicationBuilder app)
        {
            if (_IsDev)
            {
                app.ApplicationServices.GetService <TestJwtGeneratorService>();
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(o => { o.SwaggerEndpoint("v1/swagger.json", Title); });
            }

            app.UseForwardedHeaders();

            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            var iccPortalConfig = new IccPortalConfig(_Configuration);

            var corsOptions = new CorsOptions(iccPortalConfig);

            app.UseCors(corsOptions.Build);

            app.Use((context, next) =>
            {
                if (context.Request.Headers.TryGetValue("X-Forwarded-Proto", out var protoHeaderValue))
                {
                    context.Request.Scheme = protoHeaderValue;
                }

                if (context.Request.Headers.TryGetValue("X-FORWARDED-HOST", out var hostHeaderValue))
                {
                    context.Request.Host = new HostString(hostHeaderValue);
                }

                return(next());
            });

            // HttpsRedirection will be handled at the infrastructure level
            app.UseHttpsRedirection();

            app.UseSerilogRequestLogging();

            app.UseRouting();

            app.UseAuthentication();

            app.UseAuthorization();

            app.UseCookiePolicy();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
            });
        }
        private void StartupIdentityHub(IServiceCollection services)
        {
            var iccIdentityHubConfig = new IccIdentityHubConfig(_Configuration);

            services
            .AddAuthentication(auth =>
            {
                auth.DefaultChallengeScheme    = TheIdentityHubDefaults.AuthenticationScheme;
                auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                auth.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddTheIdentityHubAuthentication(options =>
            {
                options.TheIdentityHubUrl = new Uri(iccIdentityHubConfig.BaseUrl);
                options.Tenant            = iccIdentityHubConfig.Tenant;
                options.ClientId          = iccIdentityHubConfig.ClientId;
                options.ClientSecret      = iccIdentityHubConfig.ClientSecret;
                options.CallbackPath      = iccIdentityHubConfig.CallbackPath;
            });


            var iccPortalConfig = new IccPortalConfig(_Configuration);

            var policyAuthorizationOptions = new PolicyAuthorizationOptions(_WebHostEnvironment, iccPortalConfig);

            services.AddAuthorization(policyAuthorizationOptions.Build);

            services.AddScoped <ITheIdentityHubService, TheIdentityHubService>();

            services.AddMvc(config =>
            {
                config.EnableEndpointRouting = false;
                var policy = new AuthorizationPolicyBuilder()
                             .AddAuthenticationSchemes(TheIdentityHubDefaults.AuthenticationScheme)
                             .RequireAuthenticatedUser()
                             .Build();
                config.Filters.Add(new AuthorizeFilter(policy));
            });
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure <ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders =
                    ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
            });

            services.AddControllersWithViews();
            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });

            var iccPortalConfig = new IccPortalConfig(_configuration);

            services.AddRestApiClient(iccPortalConfig);

            services.AddTransient <IUtcDateTimeProvider, StandardUtcDateTimeProvider>();
            services.AddTransient <IRandomNumberGenerator, StandardRandomNumberGenerator>();
            services.AddTransient <IAuthCodeGenerator, AuthCodeGenerator>();
            services.AddSingleton <IAuthCodeService, AuthCodeService>();

            services.AddScoped <HttpGetLogoutCommand>();
            services.AddScoped <HttpGetUserClaimCommand>();
            services.AddScoped <HttpPostAuthorizationTokenCommand>();
            services.AddScoped <HttpGetAuthorisationRedirectCommand>();
            services.AddScoped <HttpGetAccessDeniedCommand>();

            services.AddSingleton <IIccPortalConfig, IccPortalConfig>();
            services.AddTransient <IJsonSerializer, StandardJsonSerializer>();
            services.AddTransient <ILuhnModNConfig, LuhnModNConfig>();
            services.AddTransient <ILuhnModNValidator, LuhnModNValidator>();
            services.AddTransient <ILuhnModNGenerator, LuhnModNGenerator>();

            services.AddTransient <IJwtService, JwtService>();

            services.AddSingleton <IAuthCodeService, AuthCodeService>();
            services.AddTransient <ILabConfirmationIdService, LabConfirmationIdService>();
            services.AddCors();

            if (_useTestJwtClaims)
            {
                services.AddTransient <IJwtClaimValidator, TestJwtClaimValidator>();
                services.AddSingleton <TestJwtGeneratorService>();
            }
            else
            {
                services.AddTransient <IJwtClaimValidator, JwtClaimValidator>();
            }

            services.AddDistributedSqlServerCache(options =>
            {
                options.ConnectionString = _configuration.GetConnectionString(DatabaseConnectionStringNames.IccDistMemCache);
                options.SchemaName       = "dbo";
                options.TableName        = "Cache";
            });

            services.AddTransient(x => x.CreateDbContext(y => new WorkflowDbContext(y), DatabaseConnectionStringNames.Workflow));
            services.AddTransient <WriteNewPollTokenWriter>();
            services.AddTransient <IPollTokenService, PollTokenService>();

            services.Configure <CookiePolicyOptions>(options =>
            {
                options.HttpOnly = HttpOnlyPolicy.Always;
                options.Secure   = CookieSecurePolicy.Always;
            });

            StartupIdentityHub(services);
            StartupAuthenticationScheme(services.AddAuthentication(JwtAuthenticationHandler.SchemeName));
        }
Beispiel #4
0
        public static IServiceCollection AddRestApiClient(this IServiceCollection services, IccPortalConfig configuration, string userAgent = null)
        {
            services.AddTransient <IHttpContextAccessor, HttpContextAccessor>();

            var userAgentValue = userAgent ?? Assembly.GetCallingAssembly().GetName().Name;

            services.AddHttpClient <IRestApiClient, RestApiClient>(client =>
            {
                client.BaseAddress = new Uri(configuration.BackendBaseUrl);
                client.DefaultRequestHeaders.Add("User-Agent", userAgentValue);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            });

            return(services);
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            services.AddLogging();
            services.AddScoped <IJsonSerializer, StandardJsonSerializer>();
            services.AddControllers(options => { options.RespectBrowserAcceptHeader = true; });

            IIccPortalConfig iccPortalConfig = new IccPortalConfig(_Configuration, "IccPortalConfig");

            services.AddSingleton(iccPortalConfig);

            // Database Scoping
            services.AddScoped(x =>
            {
                var config  = new StandardEfDbConfig(_Configuration, "WorkFlow");
                var builder = new SqlServerDbContextOptionsBuilder(config);
                var result  = new WorkflowDbContext(builder.Build());
                result.BeginTransaction();
                return(result);
            });

            services.AddScoped <HttpPostAuthoriseCommand>();
            services.AddScoped <HttpPostLabVerifyCommand>();
            services.AddScoped <AuthorisationWriterCommand>();
            services.AddScoped <IUtcDateTimeProvider, StandardUtcDateTimeProvider>();
            services.AddScoped <IRandomNumberGenerator, RandomNumberGenerator>();
            services.AddScoped <JwtService>();
            services.AddScoped <LabVerificationAuthorisationCommand>();
            services.AddScoped <PollTokens>();
            services.AddScoped <HttpGetLogoutCommand>();
            services.AddScoped <HttpGetUserClaimCommand>();
            services.AddScoped <HttpGetAuthorisationRedirectCommand>();

            services.AddMvc(config =>
            {
                config.EnableEndpointRouting = false;
                var policy = new AuthorizationPolicyBuilder()
                             .AddAuthenticationSchemes(TheIdentityHubDefaults.AuthenticationScheme)
                             .RequireAuthenticatedUser()
                             .Build();
                config.Filters.Add(new AuthorizeFilter(policy));
                // .RequireClaim(ClaimTypes.Role) //TODO still needed or dead line?
            });

            services.AddCors();

            services.AddSwaggerGen(o =>
            {
                o.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title       = "Dutch Exposure Notification ICC API (inc. dev support)",
                    Version     = "v1",
                    Description = "This specification describes the interface between the Dutch exposure notification app backend, ICC Webportal and the ICC backend service.",
                    Contact     = new OpenApiContact
                    {
                        Name = "Ministerie van Volksgezondheid Welzijn en Sport backend repository", //TODO looks wrong?
                        Url  = new Uri("https://github.com/minvws/nl-covid19-notification-app-backend"),
                    },
                    License = new OpenApiLicense
                    {
                        Name = "European Union Public License v. 1.2",
                        //TODO this should be https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
                        Url = new Uri("https://github.com/minvws/nl-covid19-notification-app-backend/blob/master/LICENSE.txt")
                    },
                });
                o.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "NL.Rijksoverheid.ExposureNotification.BackEnd.Components.xml"));
                o.AddSecurityDefinition("Icc", new OpenApiSecurityScheme
                {
                    Description = "Icc Code Authentication",
                    Name        = "Authorization",
                    In          = ParameterLocation.Header,
                    Type        = SecuritySchemeType.ApiKey,
                    Scheme      = "IccAuthentication"
                });
                o.OperationFilter <SecurityRequirementsOperationFilter>();
            });

            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            // TODO: Make service for adding authentication + configuration model
            services
            .AddAuthentication(auth => {
                auth.DefaultChallengeScheme    = TheIdentityHubDefaults.AuthenticationScheme;
                auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                auth.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddTheIdentityHubAuthentication(options =>
            {
                if (!string.IsNullOrWhiteSpace(iccPortalConfig.IdentityHubConfig.BaseUrl))
                {
                    options.TheIdentityHubUrl = new Uri(iccPortalConfig.IdentityHubConfig.BaseUrl);
                }

                //TODO if the Url is not set is there any sense to setting these?
                options.Tenant       = iccPortalConfig.IdentityHubConfig.Tenant;
                options.ClientId     = iccPortalConfig.IdentityHubConfig.ClientId;
                options.ClientSecret = iccPortalConfig.IdentityHubConfig.ClientSecret;
            });

            services.AddMvc(config =>
            {
                config.EnableEndpointRouting = false;
                var policy = new AuthorizationPolicyBuilder()
                             .AddAuthenticationSchemes(TheIdentityHubDefaults.AuthenticationScheme)
                             .RequireAuthenticatedUser()
                             .Build();
                config.Filters.Add(new AuthorizeFilter(policy));
                // .RequireClaim(ClaimTypes.Role)
            });

            services
            .AddAuthentication("jwt")
            .AddScheme <AuthenticationSchemeOptions, StandardJwtAuthenticationHandler>("jwt", null);
        }