Exemplo n.º 1
0
        public async Task <IActionResult> ExecuteFuncAsync(string functionName, Dictionary <string, object> arguments, CancellationToken cancellationToken)
        {
            var request = arguments[ScriptConstants.AzureFunctionsHttpRequestKey] as HttpRequest;

            if (CheckForInfiniteLoop(request))
            {
                return(new BadRequestObjectResult("Infinite loop detected when trying to call a local function or proxy from a proxy."));
            }

            var httpContext = request.HttpContext;

            httpContext.Items.Add(HttpExtensionConstants.AzureWebJobsUseReverseRoutesKey, true);

            var route = httpContext.GetRouteData();

            RouteContext rc = new RouteContext(httpContext);

            foreach (var router in route.Routers)
            {
                if (router is WebJobsRouter webJobsRouter)
                {
                    await webJobsRouter.RouteAsync(rc);

                    if (rc.Handler != null)
                    {
                        break;
                    }
                }
            }

            httpContext.Items.Remove(HttpExtensionConstants.AzureWebJobsUseReverseRoutesKey);
            httpContext.Items.Remove(ScriptConstants.AzureFunctionsHostKey);

            if (rc.Handler == null)
            {
                return(new NotFoundResult());
            }

            await rc.Handler.Invoke(httpContext);

            FunctionInvocationMiddleware functionInvocationMiddleware = new FunctionInvocationMiddleware(null);

            if (!httpContext.Items.TryGetValue(ScriptConstants.AzureFunctionsNestedProxyCount, out object nestedProxiesCount))
            {
                httpContext.Items.Add(ScriptConstants.AzureFunctionsNestedProxyCount, 1);
            }
            else
            {
                httpContext.Items[ScriptConstants.AzureFunctionsNestedProxyCount] = (int)nestedProxiesCount + 1;
            }

            await functionInvocationMiddleware.Invoke(httpContext);

            var result = (IActionResult)httpContext.Items[ScriptConstants.AzureFunctionsProxyResult];

            httpContext.Items.Remove(ScriptConstants.AzureFunctionsProxyResult);

            return(result);
        }
        public void RequiresAuthz_ReturnsExpectedResult()
        {
            var uri            = new Uri("http://localhost/test");
            var request        = new DefaultHttpContext().Request;
            var requestFeature = request.HttpContext.Features.Get <IHttpRequestFeature>();

            requestFeature.Method      = "GET";
            requestFeature.Scheme      = uri.Scheme;
            requestFeature.Path        = uri.GetComponents(UriComponents.KeepDelimiter | UriComponents.Path, UriFormat.Unescaped);
            requestFeature.PathBase    = string.Empty;
            requestFeature.QueryString = uri.GetComponents(UriComponents.KeepDelimiter | UriComponents.Query, UriFormat.Unescaped);

            requestFeature.Headers = new HeaderDictionary
            {
                { "Host", uri.Host }
            };

            // Function level auth requires authz
            FunctionMetadata metadata = new FunctionMetadata();
            var function  = new Mock <FunctionDescriptor>(MockBehavior.Strict, "test", null, metadata, null, null, null, null);
            var attribute = new HttpTriggerAttribute(AuthorizationLevel.Function, "get")
            {
                Route = "test"
            };

            function.SetupGet(p => p.HttpTriggerAttribute).Returns(() => attribute);
            bool result = FunctionInvocationMiddleware.RequiresAuthz(request, function.Object);

            Assert.True(result);

            // Proxies don't require authz
            metadata  = new ProxyFunctionMetadata(null);
            function  = new Mock <FunctionDescriptor>(MockBehavior.Strict, "test", null, metadata, null, null, null, null);
            attribute = new HttpTriggerAttribute(AuthorizationLevel.Function, "get")
            {
                Route = "test"
            };
            function.SetupGet(p => p.HttpTriggerAttribute).Returns(() => attribute);
            result = FunctionInvocationMiddleware.RequiresAuthz(request, function.Object);
            Assert.False(result);

            // Anonymous functions don't require authz
            metadata  = new FunctionMetadata();
            function  = new Mock <FunctionDescriptor>(MockBehavior.Strict, "test", null, metadata, null, null, null, null);
            attribute = new HttpTriggerAttribute(AuthorizationLevel.Anonymous, "get")
            {
                Route = "test"
            };
            function.SetupGet(p => p.HttpTriggerAttribute).Returns(() => attribute);
            result = FunctionInvocationMiddleware.RequiresAuthz(request, function.Object);
            Assert.False(result);

            // Anonymous functions with EasyAuth header require authz
            requestFeature.Headers = new HeaderDictionary
            {
                { ScriptConstants.EasyAuthIdentityHeader, "abc123" }
            };
            result = FunctionInvocationMiddleware.RequiresAuthz(request, function.Object);
            Assert.True(result);

            // Anonymous functions with key header require authz
            requestFeature.Headers = new HeaderDictionary
            {
                { AuthenticationLevelHandler.FunctionsKeyHeaderName, "abc123" }
            };
            result = FunctionInvocationMiddleware.RequiresAuthz(request, function.Object);
            Assert.True(result);

            // Anonymous functions with key query param require authz
            uri                        = new Uri("http://localhost/test?code=abc123");
            request                    = new DefaultHttpContext().Request;
            requestFeature             = request.HttpContext.Features.Get <IHttpRequestFeature>();
            requestFeature.Method      = "GET";
            requestFeature.Scheme      = uri.Scheme;
            requestFeature.Path        = uri.GetComponents(UriComponents.KeepDelimiter | UriComponents.Path, UriFormat.Unescaped);
            requestFeature.PathBase    = string.Empty;
            requestFeature.QueryString = uri.GetComponents(UriComponents.KeepDelimiter | UriComponents.Query, UriFormat.Unescaped);
            requestFeature.Headers     = new HeaderDictionary
            {
                { "Host", uri.Host }
            };
            result = FunctionInvocationMiddleware.RequiresAuthz(request, function.Object);
            Assert.True(result);
        }