public async Task Invoke( HttpContext context, AuthenticationManager authenticationManager, SingleSignOnHandler singleSignOnHandler, ConfigurationProvider configurationProvider, SecureRandom secureRandom ) { MemorySingletonProxyConfigProvider.Route?route = GetMatchingRoute(context); if (route != null) { bool shouldHandle = true; PathString requestPath = context.Request.Path; if (requestPath.StartsWithSegments("/.well-known/acme-challenge")) { string challenge = ((string)requestPath).Split('/').Last(); if (_acmeChallengeSingleton.Challenges.ContainsKey(challenge)) { shouldHandle = false; } } if (shouldHandle) { configurationProvider.TryGet(AuthServer.Server.GRPC.InstallService.PRIMARY_DOMAIN_KEY, out string primaryDomain); bool isAuthRequest = singleSignOnHandler.IsAuthRequest(context); if (isAuthRequest) { singleSignOnHandler.Handle(context); return; } bool isPublicEndpoint = route.PublicRoutes.Contains(context.Request.Path); if (!isPublicEndpoint) { bool isAuthenticated = authenticationManager.IsAuthenticated(context, out Guid? sessionId); if (!isAuthenticated) { string csrf = secureRandom.GetRandomString(16); context.Response.Cookies.Append("gatekeeper.csrf", csrf); Dictionary <string, string> queryDictionary = new Dictionary <string, string>() { { "id", route.ProxySettingId.ToString() }, { "csrf", csrf }, }; UriBuilder uriBuilder = new UriBuilder(); uriBuilder.Scheme = "https"; uriBuilder.Host = primaryDomain; uriBuilder.Path = "/auth/sso-connect"; uriBuilder.Query = await((new System.Net.Http.FormUrlEncodedContent(queryDictionary)).ReadAsStringAsync()); context.Response.Redirect(uriBuilder.ToString(), false); return; } else { if (sessionId == null) { // This should never happen return; } bool isAuthorized = await authenticationManager.IsAuthorizedAsync((Guid)sessionId, route); if (!isAuthorized) { context.Response.Redirect("https://" + primaryDomain + "/auth/403"); return; } } } Dictionary <string, RequestHeaderTransform> requestHeaderTransforms = new Dictionary <string, RequestHeaderTransform>() { { "X-Forwarded-For", new RequestHeaderValueTransform(context.Connection.RemoteIpAddress.ToString(), append: false) }, { "X-Forwarded-Host", new RequestHeaderValueTransform(route.PublicHostname, append: false) }, { HeaderNames.Host, new RequestHeaderValueTransform(String.Empty, append: false) } }; if (context.Request.Cookies.TryGetValue(AuthenticationManager.AUTH_COOKIE, out string?authCookieValue)) { // FIXME: This is currently also sent as cookie. Remove this and only send it as header. requestHeaderTransforms.Add( "X-Gatekeeper-Jwt-Assertion", new RequestHeaderValueTransform(authCookieValue, append: false) ); } RequestProxyOptions proxyOptions = new RequestProxyOptions() { RequestTimeout = TimeSpan.FromSeconds(100), Transforms = new Transforms( copyRequestHeaders: true, requestTransforms: Array.Empty <RequestParametersTransform>(), requestHeaderTransforms: requestHeaderTransforms, responseHeaderTransforms: new Dictionary <string, ResponseHeaderTransform>(), responseTrailerTransforms: new Dictionary <string, ResponseHeaderTransform>() ) }; await _httpProxy.ProxyAsync(context, route.InternalHostname, _httpClient, proxyOptions); return; } } await _nextMiddleware(context); }
public async Task Invoke( HttpContext context, AuthenticationManager authenticationManager, SingleSignOnHandler singleSignOnHandler, ConfigurationProvider configurationProvider, SecureRandom secureRandom ) { MemorySingletonProxyConfigProvider.Route?route = GetMatchingRoute(context); if (route != null) { bool shouldHandle = true; PathString requestPath = context.Request.Path; if (requestPath.StartsWithSegments("/.well-known/acme-challenge")) { string challenge = ((string)requestPath).Split('/').Last(); if (_acmeChallengeSingleton.Challenges.ContainsKey(challenge)) { shouldHandle = false; } } if (shouldHandle) { configurationProvider.TryGet(AuthServer.Server.GRPC.InstallService.PRIMARY_DOMAIN_KEY, out string primaryDomain); bool isAuthRequest = singleSignOnHandler.IsAuthRequest(context); if (isAuthRequest) { singleSignOnHandler.Handle(context); return; } bool isPublicEndpoint = route.PublicRoutes.Contains(context.Request.Path); if (!isPublicEndpoint) { bool isAuthenticated = authenticationManager.IsAuthenticated(context, out Guid? sessionId); if (!isAuthenticated) { string csrf = secureRandom.GetRandomString(16); context.Response.Cookies.Append("gatekeeper.csrf", csrf); Dictionary <string, string> queryDictionary = new Dictionary <string, string>() { { "id", route.ProxySettingId.ToString() }, { "csrf", csrf }, }; UriBuilder uriBuilder = new UriBuilder(); uriBuilder.Scheme = "https"; uriBuilder.Host = primaryDomain; uriBuilder.Path = "/auth/sso-connect"; uriBuilder.Query = await((new System.Net.Http.FormUrlEncodedContent(queryDictionary)).ReadAsStringAsync()); context.Response.Redirect(uriBuilder.ToString(), false); return; } else { if (sessionId == null) { // This should never happen return; } bool isAuthorized = await authenticationManager.IsAuthorizedAsync((Guid)sessionId, route); if (!isAuthorized) { context.Response.Redirect("https://" + primaryDomain + "/auth/403"); return; } } } RequestProxyOptions proxyOptions = new RequestProxyOptions( TimeSpan.FromSeconds(100), null ); await _httpProxy.ProxyAsync( context, route.InternalHostname, _httpClient, proxyOptions, new Gatekeeper.Server.Web.Services.ReverseProxy.Transformer.RequestTransformer(route) ); return; } } await _nextMiddleware(context); }