static bool SetupMethodAndContent(HttpRequest request, HttpRequestMessage proxiedMessage) { var hasContent = false; var requestMethod = request.Method; // Try to use the static HttpMethods rather than creating a new one. if (HttpMethods.IsGet(requestMethod)) { proxiedMessage.Method = HttpMethod.Get; } else if (HttpMethods.IsHead(requestMethod)) { proxiedMessage.Method = HttpMethod.Head; } else if (HttpMethods.IsDelete(requestMethod)) { proxiedMessage.Method = HttpMethod.Delete; } else if (HttpMethods.IsTrace(requestMethod)) { proxiedMessage.Method = HttpMethod.Trace; } else { hasContent = true; if (HttpMethods.IsPost(requestMethod)) { proxiedMessage.Method = HttpMethod.Post; } else if (HttpMethods.IsOptions(requestMethod)) { proxiedMessage.Method = HttpMethod.Options; } else if (HttpMethods.IsPut(requestMethod)) { proxiedMessage.Method = HttpMethod.Put; } else if (HttpMethods.IsPatch(requestMethod)) { proxiedMessage.Method = HttpMethod.Patch; } else { proxiedMessage.Method = new HttpMethod(request.Method); } proxiedMessage.Content = new StreamContent(request.Body); } return(hasContent); }
/// <summary> /// Return a corresponding VerbsHttpMethod with the verb used in the request. /// </summary> /// <param name="context">ActionExecutingContext</param> /// <returns>Return VerbsHttpMethod corresponding to the request.</returns> public static VerbsHttpMethod GetVerbs(this ActionExecutingContext context) { var method = context.HttpContext.Request.Method; if (HttpMethods.IsGet(method)) { return(VerbsHttpMethod.Get); } if (HttpMethods.IsPost(method)) { return(VerbsHttpMethod.Post); } if (HttpMethods.IsDelete(method)) { return(VerbsHttpMethod.Delete); } if (HttpMethods.IsPut(method)) { return(VerbsHttpMethod.Put); } if (HttpMethods.IsHead(method)) { return(VerbsHttpMethod.Head); } if (HttpMethods.IsOptions(method)) { return(VerbsHttpMethod.Options); } if (HttpMethods.IsPatch(method)) { return(VerbsHttpMethod.Patch); } if (HttpMethods.IsTrace(method)) { return(VerbsHttpMethod.Trace); } if (HttpMethods.IsConnect(method)) { return(VerbsHttpMethod.Connect); } throw new HttpMethodNotFoundException($"Could not find the HttpMethod '{method}'"); }
public void OnPageHandlerExecuting(PageHandlerExecutingContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.HandlerMethod == null && context.Result == null && HttpMethods.IsOptions(context.HttpContext.Request.Method)) { context.Result = new OkResult(); } }
/// <summary> /// Converts the given HTTP method (usually obtained from <see cref="HttpRequest.Method"/>) /// into the corresponding <see cref="HttpMethod"/> static instance. /// </summary> public static HttpMethod GetHttpMethod(string method) { if (HttpMethods.IsGet(method)) { return(HttpMethod.Get); } if (HttpMethods.IsPost(method)) { return(HttpMethod.Post); } if (HttpMethods.IsPut(method)) { return(HttpMethod.Put); } if (HttpMethods.IsDelete(method)) { return(HttpMethod.Delete); } if (HttpMethods.IsOptions(method)) { return(HttpMethod.Options); } if (HttpMethods.IsHead(method)) { return(HttpMethod.Head); } if (HttpMethods.IsPatch(method)) { return(HttpMethod.Patch); } if (HttpMethods.IsTrace(method)) { return(HttpMethod.Trace); } // NOTE: Proxying "CONNECT" is not supported (by design!) //if (HttpMethods.IsConnect(method)) //{ // return new HttpMethod("CONNECT"); //} throw new InvalidOperationException($"Unsupported request method '{method}'."); }
internal static bool IsValidationRequest(this HttpRequest request, out List <string> requestHosts) { if (HttpMethods.IsOptions(request.Method)) { request.Headers.TryGetValue(Constants.Headers.WebHookRequestOrigin, out StringValues requestOrigin); if (requestOrigin.Any()) { requestHosts = requestOrigin.ToList(); return(true); } } requestHosts = null; return(false); }
private static void SetRequestBody(HttpRequestMessage message, HttpContext ctx) { var method = ctx.Request.Method; if (HttpMethods.IsGet(method) || HttpMethods.IsDelete(method) || HttpMethods.IsHead(method) || HttpMethods.IsOptions(method)) { return; } var content = new StreamContent(ctx.Request.Body); message.Content = content; }
internal static bool IsPreflightRequest(this HttpRequest request, out IReadOnlyList <string> requestOrigins) { if (HttpMethods.IsOptions(request.Method)) { request.Headers.TryGetValue(Constants.Headers.WebHookRequestOrigin, out StringValues requestOrigin); if (requestOrigin.Count > 0) { requestOrigins = requestOrigin; return(true); } } requestOrigins = null; return(false); }
/// <inheritdoc /> public CorsResult EvaluatePolicy(HttpContext context, CorsPolicy policy) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (policy == null) { throw new ArgumentNullException(nameof(policy)); } if (policy.AllowAnyOrigin && policy.SupportsCredentials) { throw new ArgumentException(Resources.InsecureConfiguration, nameof(policy)); } var requestHeaders = context.Request.Headers; var origin = requestHeaders.Origin; var isOptionsRequest = HttpMethods.IsOptions(context.Request.Method); var isPreflightRequest = isOptionsRequest && requestHeaders.ContainsKey(CorsConstants.AccessControlRequestMethod); if (isOptionsRequest && !isPreflightRequest) { _logger.IsNotPreflightRequest(); } var corsResult = new CorsResult { IsPreflightRequest = isPreflightRequest, IsOriginAllowed = IsOriginAllowed(policy, origin), }; if (isPreflightRequest) { EvaluatePreflightRequest(context, policy, corsResult); } else { EvaluateRequest(context, policy, corsResult); } return(corsResult); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (HttpMethods.IsOptions(Request.Method)) { return(AuthenticateResult.NoResult()); } if (!Request.Headers.ContainsKey("Authorization")) { return(AuthenticateResult.Fail("Missing Authorization Header")); } User user = null; try { var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); var credentialBytes = Convert.FromBase64String(authHeader.Parameter); var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2); var username = credentials[0]; var password = credentials[1]; user = await _userService.Get(username, password); } catch { return(AuthenticateResult.Fail("Invalid Authorization Header")); } if (user == null) { return(AuthenticateResult.Fail("Invalid Username or Password")); } var claims = new[] { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Name, user.Username), }; var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(AuthenticateResult.Success(ticket)); }
/// <inheritdoc /> public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // If this filter is not closest to the action, it is not applicable. if (!context.IsEffectivePolicy <ICorsAuthorizationFilter>(this)) { _logger.NotMostEffectiveFilter(typeof(ICorsAuthorizationFilter)); return; } var httpContext = context.HttpContext; var request = httpContext.Request; if (request.Headers.ContainsKey(CorsConstants.Origin)) { var policy = await _corsPolicyProvider.GetPolicyAsync(httpContext, PolicyName); if (policy == null) { throw new InvalidOperationException( Resources.FormatCorsAuthorizationFilter_MissingCorsPolicy(PolicyName)); } var result = _corsService.EvaluatePolicy(context.HttpContext, policy); _corsService.ApplyResult(result, context.HttpContext.Response); var accessControlRequestMethod = httpContext.Request.Headers[CorsConstants.AccessControlRequestMethod]; if (HttpMethods.IsOptions(request.Method) && !StringValues.IsNullOrEmpty(accessControlRequestMethod)) { // If this was a preflight, there is no need to run anything else. context.Result = new StatusCodeResult(StatusCodes.Status204NoContent); } // Continue with other filters and action. } }
protected override bool ShouldValidate(AuthorizationFilterContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var method = context.HttpContext.Request.Method; if (HttpMethods.IsGet(method) || HttpMethods.IsHead(method) || HttpMethods.IsTrace(method) || HttpMethods.IsOptions(method)) { return(false); } // Anything else requires a token. return(true); }
public async Task HandleAsync(HttpContext context) { HttpRequest request = context.Request; HttpResponse response = context.Response; // Set CORS headers // Allows GETs from any origin with the Content-Type // header and caches preflight response for 3600s response.Headers.Append("Access-Control-Allow-Origin", "*"); if (HttpMethods.IsOptions(request.Method)) { response.Headers.Append("Access-Control-Allow-Methods", "GET"); response.Headers.Append("Access-Control-Allow-Headers", "Content-Type"); response.Headers.Append("Access-Control-Max-Age", "3600"); response.StatusCode = (int)HttpStatusCode.NoContent; return; } await response.WriteAsync("CORS headers set successfully!"); }
private static Method GetMethod(string method) { if (HttpMethods.IsDelete(method)) { return(Method.DELETE); } if (HttpMethods.IsGet(method)) { return(Method.GET); } if (HttpMethods.IsHead(method)) { return(Method.HEAD); } if (HttpMethods.IsOptions(method)) { return(Method.OPTIONS); } if (HttpMethods.IsPatch(method)) { return(Method.PATCH); } if (HttpMethods.IsPost(method)) { return(Method.POST); } if (HttpMethods.IsPut(method)) { return(Method.PUT); } throw new NotSupportedException($"Http Method {method} is not supported in {typeof(Method)}."); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "options", "post", Route = null)] HttpRequest req, [SignalR(HubName = "cloudEventSchemaHub")] IAsyncCollector <SignalRMessage> signalRMessages, ILogger log) { // Handle EventGrid subscription validation for CloudEventSchema v1.0. // It sets the header response `Webhook-Allowed-Origin` with the value from // the header request `Webhook-Request-Origin` // (see: https://docs.microsoft.com/en-us/azure/event-grid/cloudevents-schema#use-with-azure-functions) if (HttpMethods.IsOptions(req.Method)) { if (req.Headers.TryGetValue("Webhook-Request-Origin", out var headerValues)) { var originValue = headerValues.FirstOrDefault(); if (!string.IsNullOrEmpty(originValue)) { req.HttpContext.Response.Headers.Add("Webhook-Allowed-Origin", originValue); return(new OkResult()); } return(new BadRequestObjectResult("Missing 'Webhook-Request-Origin' header when validating")); } } // Handle an event received from EventGrid. It reads the event from the request payload and send // it to the SignalR serverless service using the Azure Function output binding if (HttpMethods.IsPost(req.Method)) { string @event = await new StreamReader(req.Body).ReadToEndAsync(); await signalRMessages.AddAsync(new SignalRMessage { Target = "newEvent", Arguments = new[] { @event } }); } return(new OkResult()); }
private static HttpMethod GetHttpMethod(string method, out bool?hasBody) { if (HttpMethods.IsDelete(method)) { hasBody = null; return(HttpMethod.Delete); } else if (HttpMethods.IsGet(method)) { hasBody = false; return(HttpMethod.Get); } else if (HttpMethods.IsHead(method)) { hasBody = false; return(HttpMethod.Head); } else if (HttpMethods.IsOptions(method)) { hasBody = null; return(HttpMethod.Options); } else if (HttpMethods.IsPost(method)) { hasBody = true; return(HttpMethod.Post); } else if (HttpMethods.IsPut(method)) { hasBody = true; return(HttpMethod.Put); } else if (HttpMethods.IsPatch(method)) { hasBody = true; return(HttpMethod.Patch); } else if (HttpMethods.IsTrace(method)) { hasBody = null; return(HttpMethod.Trace); } hasBody = null; return(new HttpMethod(method)); }
private static HttpMethod GetMethod(string method) { if (HttpMethods.IsDelete(method)) { return(HttpMethod.Delete); } if (HttpMethods.IsGet(method)) { return(HttpMethod.Get); } if (HttpMethods.IsOptions(method)) { return(HttpMethod.Options); } if (HttpMethods.IsPost(method)) { return(HttpMethod.Post); } if (HttpMethods.IsPut(method)) { return(HttpMethod.Put); } return(new HttpMethod(method)); }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger <Startup> logger) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseFileServer(); // Custom CORS to allow any origin + credentials (which isn't allowed by the CORS spec) // This is for testing purposes only (karma hosts the client on its own server), never do this in production app.Use((context, next) => { var originHeader = context.Request.Headers.Origin; if (!StringValues.IsNullOrEmpty(originHeader)) { logger.LogInformation("Setting CORS headers."); context.Response.Headers.AccessControlAllowOrigin = originHeader; context.Response.Headers.AccessControlAllowCredentials = "true"; var requestMethod = context.Request.Headers.AccessControlRequestMethod; if (!StringValues.IsNullOrEmpty(requestMethod)) { context.Response.Headers.AccessControlAllowMethods = requestMethod; } var requestHeaders = context.Request.Headers.AccessControlRequestHeaders; if (!StringValues.IsNullOrEmpty(requestHeaders)) { context.Response.Headers.AccessControlAllowHeaders = requestHeaders; } } if (HttpMethods.IsOptions(context.Request.Method)) { logger.LogInformation("Setting '204' CORS response."); context.Response.StatusCode = StatusCodes.Status204NoContent; return(Task.CompletedTask); } return(next.Invoke(context)); }); app.Use((context, next) => { if (context.Request.Path.StartsWithSegments("/echoredirect")) { var url = context.Request.Path.ToString(); url = url.Replace("echoredirect", "echo"); url += context.Request.QueryString.ToString(); context.Response.Redirect(url, false, true); return(Task.CompletedTask); } return(next.Invoke(context)); }); app.Use((context, next) => { if (context.Request.Path.StartsWithSegments("/redirect")) { var newUrl = context.Request.Query["baseUrl"] + "/testHub?numRedirects=" + Interlocked.Increment(ref _numRedirects); return(context.Response.WriteAsync($"{{ \"url\": \"{newUrl}\" }}")); } return(next(context)); }); app.Use(async(context, next) => { if (context.Request.Path.Value.Contains("/negotiate")) { var cookieOptions = new CookieOptions(); var expiredCookieOptions = new CookieOptions() { Expires = DateTimeOffset.Now.AddHours(-1) }; if (context.Request.IsHttps) { cookieOptions.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None; cookieOptions.Secure = true; expiredCookieOptions.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None; expiredCookieOptions.Secure = true; } context.Response.Cookies.Append("testCookie", "testValue", cookieOptions); context.Response.Cookies.Append("testCookie2", "testValue2", cookieOptions); cookieOptions.Expires = DateTimeOffset.Now.AddHours(-1); context.Response.Cookies.Append("expiredCookie", "doesntmatter", expiredCookieOptions); } await next.Invoke(context); }); app.Use((context, next) => { if (context.Request.Path.StartsWithSegments("/bad-negotiate")) { context.Response.StatusCode = 400; return(context.Response.WriteAsync("Some response from server")); } return(next(context)); }); app.UseRouting(); // Custom CORS to allow any origin + credentials (which isn't allowed by the CORS spec) // This is for testing purposes only (karma hosts the client on its own server), never do this in production app.UseCors(policy => { policy.SetIsOriginAllowed(host => host.StartsWith("http://localhost:", StringComparison.Ordinal) || host.StartsWith("http://127.0.0.1:", StringComparison.Ordinal)) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapHub <TestHub>("/testhub"); endpoints.MapHub <TestHub>("/testhub-nowebsockets", options => options.Transports = HttpTransportType.ServerSentEvents | HttpTransportType.LongPolling); endpoints.MapHub <UncreatableHub>("/uncreatable"); endpoints.MapHub <HubWithAuthorization>("/authorizedhub"); endpoints.MapConnectionHandler <EchoConnectionHandler>("/echo"); endpoints.MapGet("/generateJwtToken", context => { return(context.Response.WriteAsync(GenerateJwtToken())); }); endpoints.MapGet("/deployment", context => { var attributes = Assembly.GetAssembly(typeof(Startup)).GetCustomAttributes <AssemblyMetadataAttribute>(); context.Response.ContentType = "application/json"; using (var textWriter = new StreamWriter(context.Response.Body)) using (var writer = new JsonTextWriter(textWriter)) { var json = new JObject(); var commitHash = string.Empty; foreach (var attribute in attributes) { json.Add(attribute.Key, attribute.Value); if (string.Equals(attribute.Key, "CommitHash")) { commitHash = attribute.Value; } } if (!string.IsNullOrEmpty(commitHash)) { json.Add("GitHubUrl", $"https://github.com/aspnet/SignalR/commit/{commitHash}"); } json.WriteTo(writer); } return(Task.CompletedTask); }); }); }
public static bool IsCorsPreflightRequest(HttpContext httpContext) { return(HttpMethods.IsOptions(httpContext.Request.Method) && httpContext.Request.Headers.ContainsKey(HeaderNames.AccessControlRequestMethod)); }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { var isAutomaticallyApplyMigrations = EnvironmentConfiguration.GetEnvironmentVariableFromAppSettings("Database:AutomaticallyApplyMigrations") == "true"; if (isAutomaticallyApplyMigrations) { app.UpdateDatabase(); } // We want to be able to see errors in every non-prod env // Not just dev if (!env.IsProduction()) { app.UseDeveloperExceptionPage(); IdentityModelEventSource.ShowPII = true; } // We only need CORS support in development if (env.IsDevelopment()) { app.UseCors(); } app.UseHttpsRedirection(); if (env.IsDevelopment()) { // Creates an endpoint for viewing the generated // JSON schema of the API. // // Connected to note on services.ConfigureSwagger() app.UseSwagger(); } app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); // If we are not in development, try serving static files according to // the path specified in AddSpaStaticFiles. This is necessary for // returning static compiled resources like the JS and CSS. // Note that AddSpaStaticFiles is called in // ServiceExtensions.ConfigureSpa() if (!env.IsDevelopment()) { app.UseSpaStaticFiles(); } // UseSpa internally calls UseStaticFiles which only supports GET or OPTIONS // requests. Guard this middleware so only requests with those methods are // able to reach this. This prevents a 500 error when a POST/HEAD/DELETE/PUT // reaches this middleware. app.UseWhen( context => HttpMethods.IsGet(context.Request.Method) || HttpMethods.IsOptions(context.Request.Method), // UseSpa rewrites all non-endpoint requests (aka paths that do not map to // a controller). Thus, UseSpaStaticFiles must be called before UseSpa app => app.UseSpa(spa => { spa.Options.SourcePath = "ClientApp"; // If we are development, that means we aren't serving SPA files // as static, compiled resources. So we need to forward requests a // development server. if (env.IsDevelopment()) { var isDocker = Environment.GetEnvironmentVariable("DOCKER_DEVELOPMENT"); // If we are using docker (compose), the client container will serve // responses for us. We need to forward to its hostname. if (isDocker == "true") { string CLIENT_HOST = Environment.GetEnvironmentVariable("CLIENT_HOST") ?? "http://localhost:3000"; spa.UseProxyToSpaDevelopmentServer(CLIENT_HOST); } // If we aren't using docker, we need .NET to create a server for us // to serve responses. else { // Note: While the parameter is called npmScript it will also run yarn // scripts. Specifically, it will run the corresponding package.json // script and provided the referenced executable exists on the path // the script will run. spa.UseReactDevelopmentServer(npmScript: "start"); } } // If we aren't in development, UseSpa will internally call UseStaticFiles // on the directory specified by AddSpaStaticFiles }) ); // Catch any remaining requests and return 404 not found app.Run( context => { context.Response.StatusCode = StatusCodes.Status404NotFound; return(Task.CompletedTask); }); }
/// <inheritdoc /> public async Task <bool> IsRequestValidAsync(HttpContext httpContext) { if (httpContext == null) { throw new ArgumentNullException(nameof(httpContext)); } CheckSSLConfig(httpContext); var method = httpContext.Request.Method; if (HttpMethods.IsGet(method) || HttpMethods.IsHead(method) || HttpMethods.IsOptions(method) || HttpMethods.IsTrace(method)) { // Validation not needed for these request types. return(true); } var tokens = await _tokenStore.GetRequestTokensAsync(httpContext); if (tokens.CookieToken == null) { _logger.MissingCookieToken(_options.Cookie.Name); return(false); } if (tokens.RequestToken == null) { _logger.MissingRequestToken(_options.FormFieldName, _options.HeaderName); return(false); } // Extract cookie & request tokens AntiforgeryToken deserializedCookieToken; AntiforgeryToken deserializedRequestToken; if (!TryDeserializeTokens(httpContext, tokens, out deserializedCookieToken, out deserializedRequestToken)) { return(false); } // Validate var result = _tokenGenerator.TryValidateTokenSet( httpContext, deserializedCookieToken, deserializedRequestToken, out string message); if (result) { _logger.ValidatedAntiforgeryToken(); } else { _logger.ValidationFailed(message); } return(result); }
static bool ShouldValidate(ActionContext context) { return(!HttpMethods.IsGet(context.HttpContext.Request.Method) && !HttpMethods.IsHead(context.HttpContext.Request.Method) && !HttpMethods.IsOptions(context.HttpContext.Request.Method)); }
/// <inheritdoc /> public Task Invoke(HttpContext context, ICorsPolicyProvider corsPolicyProvider) { // CORS policy resolution rules: // // 1. If there is an endpoint with IDisableCorsAttribute then CORS is not run // 2. If there is an endpoint with ICorsPolicyMetadata then use its policy or if // there is an endpoint with IEnableCorsAttribute that has a policy name then // fetch policy by name, prioritizing it above policy on middleware // 3. If there is no policy on middleware then use name on middleware var endpoint = context.GetEndpoint(); if (endpoint != null) { // EndpointRoutingMiddleware uses this flag to check if the CORS middleware processed CORS metadata on the endpoint. // The CORS middleware can only make this claim if it observes an actual endpoint. context.Items[CorsMiddlewareWithEndpointInvokedKey] = CorsMiddlewareWithEndpointInvokedValue; } if (!context.Request.Headers.ContainsKey(CorsConstants.Origin)) { return(_next(context)); } // Get the most significant CORS metadata for the endpoint // For backwards compatibility reasons this is then downcast to Enable/Disable metadata var corsMetadata = endpoint?.Metadata.GetMetadata <ICorsMetadata>(); if (corsMetadata is IDisableCorsAttribute) { var isOptionsRequest = HttpMethods.IsOptions(context.Request.Method); var isCorsPreflightRequest = isOptionsRequest && context.Request.Headers.ContainsKey(CorsConstants.AccessControlRequestMethod); if (isCorsPreflightRequest) { // If this is a preflight request, and we disallow CORS, complete the request context.Response.StatusCode = StatusCodes.Status204NoContent; return(Task.CompletedTask); } return(_next(context)); } var corsPolicy = _policy; var policyName = _corsPolicyName; if (corsMetadata is ICorsPolicyMetadata corsPolicyMetadata) { policyName = null; corsPolicy = corsPolicyMetadata.Policy; } else if (corsMetadata is IEnableCorsAttribute enableCorsAttribute && enableCorsAttribute.PolicyName != null) { // If a policy name has been provided on the endpoint metadata then prioritizing it above the static middleware policy policyName = enableCorsAttribute.PolicyName; corsPolicy = null; } if (corsPolicy == null) { // Resolve policy by name if the local policy is not being used var policyTask = corsPolicyProvider.GetPolicyAsync(context, policyName); if (!policyTask.IsCompletedSuccessfully) { return(InvokeCoreAwaited(context, policyTask)); } corsPolicy = policyTask.Result; } return(EvaluateAndApplyPolicy(context, corsPolicy)); async Task InvokeCoreAwaited(HttpContext context, Task <CorsPolicy?> policyTask) { var corsPolicy = await policyTask; await EvaluateAndApplyPolicy(context, corsPolicy); } }