Пример #1
0
        // 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)
        {
            var settings = new WPProxySettings();

            Configuration.GetSection("WPProxy").Bind(settings);

            if (!settings.UseRedis)
            {
                services.AddDistributedMemoryCache();
            }
            else
            {
                services.AddStackExchangeRedisCache(cnf =>
                {
                    cnf.InstanceName  = settings.RedisInstanceName;
                    cnf.Configuration = $"{settings.RedisIpAddress}:{settings.RedisPort},DefaultDatabase=1";
                });

                // Ensure cookies work across all container instances
                var redis = ConnectionMultiplexer.Connect($"{settings.RedisIpAddress}:{settings.RedisPort}");
                services.AddDataProtection()
                .PersistKeysToStackExchangeRedis(redis, "wp-proxy-dataprotection-keys");
            }
            services.AddMemoryCache();

            var cacheProvider = services.BuildServiceProvider();

            if (string.IsNullOrEmpty(settings.GoogleStorageBucket))
            {
                services.AddSingleton <IFileStore>(c => new PhysicalFileStore(new PhysicalFileProvider(Directory.GetCurrentDirectory() + "/Files")));
            }
            else
            {
                services.AddSingleton <IFileStore>(c => new GCPStorageStore(settings, cacheProvider.GetRequiredService <IDistributedCache>()));
            }

            services.AddSingleton(c => settings);
            services.AddSingleton <EndpointSelector, WPProxyEndpointSelector>();
            services.AddHttpProxy();
            services.AddHttpClient();
            services.AddReverseProxy().AddConfig();
            //services.AddAuthorization(options =>
            //{
            //    options.AddPolicy(WPProxySettings.AuthorizationPolicy, policy =>
            //    {
            //        policy.RequireAuthenticatedUser();
            //    });
            //});

            services.AddSingleton <IAuthorizationPolicyProvider, WPProxyAuthorizationPolicy>();


            services.Configure <CookiePolicyOptions>(options =>
            {
                options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Unspecified;
                options.Secure         = CookieSecurePolicy.SameAsRequest;
                options.OnAppendCookie = cookieContext => CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
                options.OnDeleteCookie = cookieContext => CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
            });

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme    = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie(o =>
            {
                if (settings.UseRedis)
                {
                    o.SessionStore = new RedisSessionStore(cacheProvider.GetRequiredService <IMemoryCache>(), cacheProvider.GetRequiredService <IDistributedCache>());
                }
                else
                {
                    o.SessionStore = new InMemorySessionStore();
                }
            })
            .AddOpenIdConnect("Auth0", options =>
            {
                // Set the authority to your Auth0 domain
                options.Authority = Configuration["Authentication:Authority"];

                // Configure the Auth0 Client ID and Client Secret
                options.ClientId     = Configuration["Authentication:ClientId"];
                options.ClientSecret = Configuration["Authentication:ClientSecret"];

                options.Events.OnRedirectToIdentityProvider = context =>
                {
                    // Required for getting access token in JWT format (for widgets)
                    context.ProtocolMessage.SetParameter("audience", Configuration["Authentication:Audience"]);
                    return(Task.CompletedTask);
                };

                options.Events.OnRedirectToIdentityProviderForSignOut = context =>
                {
                    context.ProtocolMessage.IssuerAddress =
                        $"{Configuration["Authentication:Authority"].TrimEnd('/')}/{Configuration["Authentication:LogoutEndpoint"].TrimStart('/')}";
                    return(Task.CompletedTask);
                };

                options.Events.OnRemoteFailure = context =>
                {
                    var log          = context.HttpContext.RequestServices.GetService <ILogger <Startup> >();
                    var errorMessage = "Login callback failed with following error: " + (context.Failure?.Message ?? "");
                    var hasUserAgent = context.HttpContext.Request.Headers.TryGetValue(HeaderNames.UserAgent, out StringValues userAgent);
                    if (hasUserAgent)
                    {
                        errorMessage += ". User Agent: " + userAgent.ToString();
                    }
                    var hasReferer = context.HttpContext.Request.Headers.TryGetValue(HeaderNames.Referer, out StringValues referer);
                    if (hasReferer)
                    {
                        errorMessage += ". Referrer: " + referer.ToString();
                    }

                    log.LogError(context.Failure, errorMessage);

                    return(Task.CompletedTask);
                };

                // Set response type to code
                options.ResponseType = OpenIdConnectResponseType.Code;


                options.SaveTokens = true;

                options.GetClaimsFromUserInfoEndpoint = false;

                options.UseTokenLifetime = true;

                // Configure the scope
                options.Scope.Clear();
                options.Scope.Add(Configuration["Authentication:Scopes"]);

                // Set the callback path, so Auth0 will call back to /callback
                // Also ensure that you have added the URL as an Allowed Callback URL in your Auth0 dashboard
                options.CallbackPath = new PathString("/callback");

                // Configure the Claims Issuer to be Auth0
                options.ClaimsIssuer = "Auth0";
            });


            // Add framework services.
            services.AddControllersWithViews();

            services.AddSingleton <WPCacheService>();
            services.AddSingleton <WPApiClient>();
            services.AddSingleton <WPUserService>();
            services.AddSingleton <WPMessageHandler>();
            services.AddSingleton <WPMessageInvokerFactory>();
            services.AddSingleton <WPProxySiteSettingsAccessor>();
            services.AddApplicationInsightsTelemetry();
        }
Пример #2
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHttpProxy httpProxy, WPMessageInvokerFactory messageInvoker, WPProxySettings settings)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }


            app.UseStaticFiles();
            app.UseRouting();
            app.UseCookiePolicy();
            app.UseAuthentication();
            app.UseAuthorization();


            app.Use(next => context =>
            {
                // Force https scheme (since request inside a docker container may appear to be http)
                context.Request.Scheme = "https";
                return(next(context));
            });

            var transformer    = new WPRequestTransformer(); // or HttpTransformer.Default;
            var requestOptions = new RequestProxyOptions {
                Timeout       = TimeSpan.FromSeconds(100),
                Version       = new Version(1, 1), // Not all servers support HTTP 2
                VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher
            };

            app.UseEndpoints(endpoints =>
            {
                // Dont't authenticate manifest.json
                endpoints.Map("/manifest.json", async httpContext => //
                {
                    var siteSettings = settings.GetForHost(httpContext.Request.Host.ToString());
                    await httpProxy.ProxyAsync(httpContext, siteSettings.SourceAddress, messageInvoker.Create(), requestOptions, transformer);
                });

                endpoints.Map("/{**catch-all}", async httpContext => //
                {
                    var siteSettings = settings.GetForHost(httpContext.Request.Host.ToString());
                    await httpProxy.ProxyAsync(httpContext, siteSettings.SourceAddress, messageInvoker.Create(), requestOptions, transformer);

                    var errorFeature = httpContext.Features.Get <IProxyErrorFeature>();
                    if (errorFeature != null)
                    {
                        var error     = errorFeature.Error;
                        var exception = errorFeature.Exception;
                        throw errorFeature.Exception;
                    }
                })
                .RequireAuthorization(WPProxySettings.AuthorizationPolicy);

                endpoints.MapDefaultControllerRoute();
            });
        }