コード例 #1
0
        public async Task Invoke(HttpContext context, WebScriptHostManager manager)
        {
            // flow required context through the request pipeline
            // downstream middleware and filters rely on this
            context.Items[ScriptConstants.AzureFunctionsHostManagerKey] = manager;
            SetRequestId(context.Request);

            if (_next != null)
            {
                await _next(context);
            }

            IFunctionExecutionFeature functionExecution = context.Features.Get <IFunctionExecutionFeature>();

            if (functionExecution != null && !context.Response.HasStarted)
            {
                int           nestedProxiesCount = GetNestedProxiesCount(context, functionExecution);
                IActionResult result             = await GetResultAsync(context, functionExecution);

                if (nestedProxiesCount > 0)
                {
                    // if Proxy, the rest of the pipleline will be processed by Proxies in
                    // case there are response overrides and what not.
                    SetProxyResult(context, nestedProxiesCount, result);
                    return;
                }

                var actionContext = new ActionContext
                {
                    HttpContext = context
                };

                await result.ExecuteResultAsync(actionContext);
            }
        }
コード例 #2
0
        public async Task Invoke(HttpContext context)
        {
            if (_next != null)
            {
                await _next(context);
            }

            _applicationLifetime = context.RequestServices.GetService <IApplicationLifetime>();

            IFunctionExecutionFeature functionExecution = context.Features.Get <IFunctionExecutionFeature>();

            if (functionExecution != null && !context.Response.HasStarted())
            {
                int           nestedProxiesCount = GetNestedProxiesCount(context, functionExecution);
                IActionResult result             = await GetResultAsync(context, functionExecution);

                if (nestedProxiesCount > 0)
                {
                    // if Proxy, the rest of the pipleline will be processed by Proxies in
                    // case there are response overrides and what not.
                    SetProxyResult(context, nestedProxiesCount, result);
                    return;
                }

                ActionContext actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
                await result.ExecuteResultAsync(actionContext);
            }
        }
        private async Task <IActionResult> GetResultAsync(HttpContext context, IFunctionExecutionFeature functionExecution)
        {
            if (functionExecution.Descriptor == null)
            {
                return(new NotFoundResult());
            }

            if (context.Request.IsColdStart() && !context.Items.ContainsKey(ScriptConstants.AzureFunctionsColdStartKey))
            {
                // for cold start requests we want to measure the request
                // pipeline dispatch time
                // important that this stopwatch is started as early as possible
                // in the pipeline (in this case, in our first middleware)
                var sw = new Stopwatch();
                sw.Start();
                context.Items[ScriptConstants.AzureFunctionsColdStartKey] = sw;
            }

            PopulateRouteData(context);

            bool authorized = await AuthenticateAndAuthorizeAsync(context, functionExecution.Descriptor);

            if (!authorized)
            {
                return(new UnauthorizedResult());
            }

            // If the function is disabled, return 'NotFound', unless the request is being made with Admin credentials
            if (functionExecution.Descriptor.Metadata.IsDisabled() &&
                !AuthUtility.PrincipalHasAuthLevelClaim(context.User, AuthorizationLevel.Admin))
            {
                return(new NotFoundResult());
            }

            if (functionExecution.CanExecute)
            {
                // Add the request to the logging scope. This allows the App Insights logger to
                // record details about the request.
                ILoggerFactory loggerFactory = context.RequestServices.GetService <ILoggerFactory>();
                ILogger        logger        = loggerFactory.CreateLogger(LogCategories.CreateFunctionCategory(functionExecution.Descriptor.Name));
                var            scopeState    = new Dictionary <string, object>()
                {
                    [ScriptConstants.LoggerHttpRequest] = context.Request,
                };

                using (logger.BeginScope(scopeState))
                {
                    var applicationLifetime             = context.RequestServices.GetService <IApplicationLifetime>();
                    CancellationToken cancellationToken = applicationLifetime != null ? applicationLifetime.ApplicationStopping : CancellationToken.None;
                    await functionExecution.ExecuteAsync(context.Request, cancellationToken);
                }
            }

            if (context.Items.TryGetValue(ScriptConstants.AzureFunctionsHttpResponseKey, out object result) && result is IActionResult actionResult)
            {
                return(actionResult);
            }

            return(new OkResult());
        }
コード例 #4
0
        public async Task Invoke(HttpContext context)
        {
            // TODO: DI Need to make sure downstream services are getting what they need
            // that includes proxies.
            //if (scriptHost != null)
            //{
            //    // flow required context through the request pipeline
            //    // downstream middleware and filters rely on this
            //    context.Items[ScriptConstants.AzureFunctionsHostKey] = scriptHost;
            //}

            if (_next != null)
            {
                await _next(context);
            }

            IFunctionExecutionFeature functionExecution = context.Features.Get <IFunctionExecutionFeature>();

            if (functionExecution != null && !context.Response.HasStarted())
            {
                int           nestedProxiesCount = GetNestedProxiesCount(context, functionExecution);
                IActionResult result             = await GetResultAsync(context, functionExecution);

                if (nestedProxiesCount > 0)
                {
                    // if Proxy, the rest of the pipleline will be processed by Proxies in
                    // case there are response overrides and what not.
                    SetProxyResult(context, nestedProxiesCount, result);
                    return;
                }

                ActionContext actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
                await result.ExecuteResultAsync(actionContext);
            }
        }
        private static int GetNestedProxiesCount(HttpContext context, IFunctionExecutionFeature functionExecution)
        {
            context.Items.TryGetValue(ScriptConstants.AzureFunctionsNestedProxyCount, out object nestedProxiesCount);

            if (nestedProxiesCount != null)
            {
                return((int)nestedProxiesCount);
            }

            return(0);
        }
コード例 #6
0
        internal static async Task <(string, AuthorizationLevel)> GetAuthorizationKeyInfoAsync(HttpRequest request, ISecretManagerProvider secretManagerProvider)
        {
            // first see if a key value is specified via headers or query string (header takes precedence)
            string keyValue = null;

            if (request.Headers.TryGetValue(FunctionsKeyHeaderName, out StringValues values))
            {
                keyValue = values.First();
            }
            else if (request.Query.TryGetValue("code", out values))
            {
                keyValue = values.First();
            }

            if (!string.IsNullOrEmpty(keyValue))
            {
                ISecretManager secretManager = secretManagerProvider.Current;

                // see if the key specified is the master key
                HostSecretsInfo hostSecrets = await secretManager.GetHostSecretsAsync().ConfigureAwait(false);

                if (!string.IsNullOrEmpty(hostSecrets.MasterKey) &&
                    Key.SecretValueEquals(keyValue, hostSecrets.MasterKey))
                {
                    return(ScriptConstants.DefaultMasterKeyName, AuthorizationLevel.Admin);
                }

                if (HasMatchingKey(hostSecrets.SystemKeys, keyValue, out string keyName))
                {
                    return(keyName, AuthorizationLevel.System);
                }

                // see if the key specified matches the host function key
                if (HasMatchingKey(hostSecrets.FunctionKeys, keyValue, out keyName))
                {
                    return(keyName, AuthorizationLevel.Function);
                }

                // If there is a function specific key specified try to match against that
                IFunctionExecutionFeature executionFeature = request.HttpContext.Features.Get <IFunctionExecutionFeature>();
                if (executionFeature != null)
                {
                    IDictionary <string, string> functionSecrets = await secretManager.GetFunctionSecretsAsync(executionFeature.Descriptor.Name);

                    if (HasMatchingKey(functionSecrets, keyValue, out keyName))
                    {
                        return(keyName, AuthorizationLevel.Function);
                    }
                }
            }

            return(null, AuthorizationLevel.Anonymous);
        }
        private async Task <IActionResult> GetResultAsync(HttpContext context, IFunctionExecutionFeature functionExecution)
        {
            if (functionExecution.Descriptor == null)
            {
                return(new NotFoundResult());
            }

            // Add route data to request info
            // TODO: Keeping this here for now as other code depend on this property, but this can be done in the HTTP binding.
            var routingFeature = context.Features.Get <IRoutingFeature>();

            context.Items.Add(HttpExtensionConstants.AzureWebJobsHttpRouteDataKey, new Dictionary <string, object>(routingFeature.RouteData.Values));

            bool authorized = await AuthenticateAndAuthorizeAsync(context, functionExecution.Descriptor);

            if (!authorized)
            {
                return(new UnauthorizedResult());
            }

            // If the function is disabled, return 'NotFound', unless the request is being made with Admin credentials
            if (functionExecution.Descriptor.Metadata.IsDisabled &&
                !AuthUtility.PrincipalHasAuthLevelClaim(context.User, AuthorizationLevel.Admin))
            {
                return(new NotFoundResult());
            }

            if (functionExecution.CanExecute)
            {
                // Add the request to the logging scope. This allows the App Insights logger to
                // record details about the request.
                ILogger logger     = _loggerFactory.CreateLogger(LogCategories.Function);
                var     scopeState = new Dictionary <string, object>()
                {
                    [ScriptConstants.LoggerHttpRequest] = context.Request
                };

                using (logger.BeginScope(scopeState))
                {
                    // TODO: Flow cancellation token from caller
                    await functionExecution.ExecuteAsync(context.Request, CancellationToken.None);
                }
            }

            if (context.Items.TryGetValue(ScriptConstants.AzureFunctionsHttpResponseKey, out object result) && result is IActionResult actionResult)
            {
                return(actionResult);
            }

            return(new OkResult());
        }
        public async Task Invoke(HttpContext context)
        {
            await _next(context);

            IFunctionExecutionFeature functionExecution = context.Features.Get <IFunctionExecutionFeature>();

            if (functionExecution != null && !context.Response.HasStarted)
            {
                IActionResult result = await GetResultAsync(context, functionExecution);

                var actionContext = new ActionContext
                {
                    HttpContext = context
                };

                await result.ExecuteResultAsync(actionContext);
            }
        }
コード例 #9
0
        private static int GetNestedProxiesCount(HttpContext context, IFunctionExecutionFeature functionExecution)
        {
            context.Items.TryGetValue(ScriptConstants.AzureFunctionsNestedProxyCount, out object nestedProxiesCount);

            if (functionExecution != null && !functionExecution.Descriptor.Metadata.IsProxy && nestedProxiesCount == null)
            {
                // HttpBufferingService is disabled for non-proxy functions.
                var bufferingFeature = context.Features.Get <IScriptHttpBufferedStream>();
                bufferingFeature?.DisableBufferingAsync(CancellationToken.None);
            }

            if (nestedProxiesCount != null)
            {
                return((int)nestedProxiesCount);
            }

            return(0);
        }
コード例 #10
0
        private static int GetNestedProxiesCount(HttpContext context, IFunctionExecutionFeature functionExecution)
        {
            context.Items.TryGetValue(ScriptConstants.AzureFunctionsNestedProxyCount, out object nestedProxiesCount);

            //HttpBufferingService is disabled for non - proxy functions.
            if (functionExecution != null && !functionExecution.Descriptor.Metadata.IsProxy && nestedProxiesCount == null)
            {
                var bufferingFeature = context.Features.Get <IHttpBufferingFeature>();
                bufferingFeature?.DisableRequestBuffering();
                bufferingFeature?.DisableResponseBuffering();
            }

            if (nestedProxiesCount != null)
            {
                return((int)nestedProxiesCount);
            }

            return(0);
        }
コード例 #11
0
        public async Task Invoke(HttpContext context, WebScriptHostManager manager)
        {
            // flow required context through the request pipeline
            // downstream middleware and filters rely on this
            context.Items.Add(ScriptConstants.AzureFunctionsHostManagerKey, manager);
            SetRequestId(context.Request);
            await _next(context);

            IFunctionExecutionFeature functionExecution = context.Features.Get <IFunctionExecutionFeature>();

            if (functionExecution != null && !context.Response.HasStarted)
            {
                IActionResult result = await GetResultAsync(context, functionExecution);

                var actionContext = new ActionContext
                {
                    HttpContext = context
                };

                await result.ExecuteResultAsync(actionContext);
            }
        }
コード例 #12
0
        public async Task Invoke(HttpContext context, WebScriptHostManager manager)
        {
            await _next(context);

            IFunctionExecutionFeature functionExecution = context.Features.Get <IFunctionExecutionFeature>();

            if (functionExecution == null &&
                context.Request.Path.Value == "/")
            {
                IActionResult result = null;

                if (IsHomepageDisabled || context.Request.IsAntaresInternalRequest())
                {
                    result = new NoContentResult();
                }
                else
                {
                    result = new ContentResult()
                    {
                        Content     = GetHomepage(),
                        ContentType = "text/html",
                        StatusCode  = 200
                    };
                }

                if (!context.Response.HasStarted)
                {
                    var actionContext = new ActionContext
                    {
                        HttpContext = context
                    };

                    await result.ExecuteResultAsync(actionContext);
                }
            }
        }