Exemplo n.º 1
0
            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}'");
        }
Exemplo n.º 3
0
        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();
            }
        }
Exemplo n.º 4
0
        /// <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);
 }
Exemplo n.º 6
0
        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);
 }
Exemplo n.º 8
0
    /// <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));
    }
Exemplo n.º 10
0
    /// <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.
        }
    }
Exemplo n.º 11
0
        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);
        }
Exemplo n.º 12
0
        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!");
        }
Exemplo n.º 13
0
        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)}.");
        }
Exemplo n.º 14
0
        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());
        }
Exemplo n.º 15
0
 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));
 }
Exemplo n.º 17
0
        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);
                });
            });
        }
Exemplo n.º 18
0
 public static bool IsCorsPreflightRequest(HttpContext httpContext)
 {
     return(HttpMethods.IsOptions(httpContext.Request.Method) &&
            httpContext.Request.Headers.ContainsKey(HeaderNames.AccessControlRequestMethod));
 }
Exemplo n.º 19
0
        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);
            });
        }
Exemplo n.º 20
0
        /// <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);
        }
Exemplo n.º 21
0
 static bool ShouldValidate(ActionContext context)
 {
     return(!HttpMethods.IsGet(context.HttpContext.Request.Method) &&
            !HttpMethods.IsHead(context.HttpContext.Request.Method) &&
            !HttpMethods.IsOptions(context.HttpContext.Request.Method));
 }
Exemplo n.º 22
0
        /// <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);
            }
        }