/// <summary> /// Handles the actual CORS request. /// </summary> /// <param name="request">The <see cref="HttpRequestMessage"/>.</param> /// <param name="corsRequestContext">The <see cref="CorsRequestContext"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <returns>The <see cref="Task{HttpResponseMessage}"/>.</returns> /// <exception cref="System.ArgumentNullException"> /// request /// or /// corsRequestContext /// </exception> public virtual async Task<HttpResponseMessage> HandleCorsRequestAsync(HttpRequestMessage request, CorsRequestContext corsRequestContext, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (request == null) { throw new ArgumentNullException("request"); } if (corsRequestContext == null) { throw new ArgumentNullException("corsRequestContext"); } HttpResponseMessage response = await base.SendAsync(request, cancellationToken); CorsPolicy corsPolicy = await GetCorsPolicyAsync(request); if (corsPolicy != null) { CorsResult result; if (TryEvaluateCorsPolicy(corsRequestContext, corsPolicy, out result)) { if (response != null) { response.WriteCorsHeaders(result); } } } return response; }
/// <summary> /// Try to validate the requested method based on <see cref="CorsPolicy"/>. /// </summary> /// <param name="requestContext">The <see cref="CorsRequestContext"/>.</param> /// <param name="policy">The <see cref="CorsPolicy"/>.</param> /// <param name="result">The <see cref="CorsResult"/>.</param> /// <returns><c>true</c> if the requested method is valid; otherwise, <c>false</c>. </returns> /// <exception cref="System.ArgumentNullException"> /// requestContext /// or /// policy /// or /// result /// </exception> public virtual bool TryValidateMethod(CorsRequestContext requestContext, CorsPolicy policy, CorsResult result) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (policy == null) { throw new ArgumentNullException("policy"); } if (result == null) { throw new ArgumentNullException("result"); } if (policy.AllowAnyMethod || policy.Methods.Contains(requestContext.AccessControlRequestMethod)) { result.AllowedMethods.Add(requestContext.AccessControlRequestMethod); } else { result.ErrorMessages.Add(String.Format( CultureInfo.CurrentCulture, SRResources.MethodNotAllowed, requestContext.AccessControlRequestMethod)); } return result.IsValid; }
public CorsResult EvaluatePolicy(CorsRequestContext requestContext, CorsPolicy policy) { CorsResult corsResult = null; object request; requestContext.Properties.TryGetValue(typeof(HttpRequestMessage).FullName, out request); _traceWriter.TraceBeginEnd( request as HttpRequestMessage, TraceCategories.CorsCategory, TraceLevel.Info, _innerCorsEngine.GetType().Name, MethodName, beginTrace: null, execute: () => { corsResult = _innerCorsEngine.EvaluatePolicy(requestContext, policy); }, endTrace: (tr) => { if (corsResult != null) { tr.Message = String.Format(CultureInfo.CurrentCulture, SRResources.TraceEndCorsResultReturned, corsResult); } else { tr.Message = SRResources.TraceEndNoCorsResultReturned; } }, errorTrace: null); return corsResult; }
public static IDictionary<string, string> GetCorsResponseHeaders( this CorsEngine corsEngine, CorsRequestContext context, CorsOptions options) { return corsEngine .EvaluatePolicy(context, options.GetCorsPolicy()) .ToResponseHeaders() ?? new Dictionary<string, string>(); }
public static bool EvaluateCorsPolicy( this CorsEngine corsEngine, CorsRequestContext context, CorsOptions options) { var result = corsEngine.EvaluatePolicy(context, options.GetCorsPolicy()); return result.IsNotNull() && result.IsValid; }
private Task HandleCorsRequestAsync(IOwinContext context, CorsPolicy policy, CorsRequestContext corsRequestContext) { CorsResult result; if (TryEvaluateCorsPolicy(policy, corsRequestContext, out result)) { WriteCorsHeaders(context, result); } return _next(context.Environment); }
private Task HandleCorsPreflightRequestAsync(IOwinContext context, CorsPolicy policy, CorsRequestContext corsRequestContext) { CorsResult result; if (!String.IsNullOrEmpty(corsRequestContext.AccessControlRequestMethod) && TryEvaluateCorsPolicy(policy, corsRequestContext, out result)) { context.Response.StatusCode = 200; WriteCorsHeaders(context, result); } else { // We couldn't evaluate the cors policy so it's a bad request context.Response.StatusCode = 400; } return Task.FromResult(0); }
public static CorsRequestContext CreateCorsRequestContext(this HttpRequestMessage request) { CorsRequestContext context = new CorsRequestContext { RequestUri = request.RequestUri, HttpMethod = request.Method.Method, Host = request.Headers.Host, Origin = request.GetHeader("Origin"), AccessControlRequestMethod = request.GetHeader("Access-Control-Request-Method") }; string requestHeaders = request.GetHeader("Access-Control-Request-Headers"); if (!string.IsNullOrEmpty(requestHeaders)) { Array.ForEach(requestHeaders.Split(','), header => context.AccessControlRequestHeaders.Add(header.Trim())); } return context; }
/// <summary> /// Gets the <see cref="CorsRequestContext"/> for a given request. /// </summary> /// <param name="request">The <see cref="HttpRequestMessage"/>.</param> /// <returns>The <see cref="CorsRequestContext"/>.</returns> /// <exception cref="System.ArgumentNullException">request</exception> public static CorsRequestContext GetCorsRequestContext(this HttpRequestMessage request) { if (request == null) { throw new ArgumentNullException("request"); } object corsRequestContext; if (!request.Properties.TryGetValue(CorsRequestContextKey, out corsRequestContext)) { if (!request.Headers.Contains(CorsConstants.Origin)) { return null; } CorsRequestContext requestContext = new CorsRequestContext { RequestUri = request.RequestUri, HttpMethod = request.Method.Method, Host = request.Headers.Host, Origin = request.GetHeader(CorsConstants.Origin), AccessControlRequestMethod = request.GetHeader(CorsConstants.AccessControlRequestMethod) }; requestContext.Properties.Add(typeof(HttpRequestMessage).FullName, request); IEnumerable<string> accessControlRequestHeaders = request.GetHeaders(CorsConstants.AccessControlRequestHeaders); foreach (string accessControlRequestHeader in accessControlRequestHeaders) { if (accessControlRequestHeader != null) { IEnumerable<string> headerValues = accessControlRequestHeader.Split(',').Select(x => x.Trim()); foreach (string header in headerValues) { requestContext.AccessControlRequestHeaders.Add(header); } } } request.Properties.Add(CorsRequestContextKey, requestContext); corsRequestContext = requestContext; } return (CorsRequestContext)corsRequestContext; }
public override bool TryValidateOrigin(CorsRequestContext requestContext, CorsPolicy policy, CorsResult result) { if (requestContext == null) { throw new ArgumentNullException(nameof(requestContext)); } if (policy == null) { throw new ArgumentNullException(nameof(policy)); } if (result == null) { throw new ArgumentNullException(nameof(result)); } if (requestContext.Origin != null) { if (policy.AllowAnyOrigin) { if (policy.SupportsCredentials) { result.AllowedOrigin = requestContext.Origin; } else { result.AllowedOrigin = CorsConstants.AnyOrigin; } } else if (policy.Origins.Any(x => UrlExtensions.IsSubdomainOf(requestContext.Origin, x))) { result.AllowedOrigin = requestContext.Origin; } else { result.ErrorMessages.Add($"Origin {requestContext.Origin} not allowed"); } } else { result.ErrorMessages.Add("No origin header present"); } return result.IsValid; }
public virtual bool TryValidateOrigin(CorsRequestContext requestContext, CorsPolicy policy, CorsResult result) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (policy == null) { throw new ArgumentNullException("policy"); } if (result == null) { throw new ArgumentNullException("result"); } if (requestContext.Origin != null) { if (policy.AllowAnyOrigin) { if (policy.SupportsCredentials) { result.AllowedOrigin = requestContext.Origin; } else { result.AllowedOrigin = CorsConstants.AnyOrigin; } } else if (policy.Origins.Contains(requestContext.Origin)) { result.AllowedOrigin = requestContext.Origin; } else { result.ErrorMessages.Add(string.Format(CultureInfo.CurrentCulture, "OriginNotAllowed=The origin '{0}' is not allowed.", new object[] { requestContext.Origin })); } } else { result.ErrorMessages.Add("The request does not contain the Origin header."); } return(result.IsValid); }
/// <summary> /// Evaluates the policy. /// </summary> /// <param name="requestContext">The <see cref="CorsRequestContext" />.</param> /// <param name="policy">The <see cref="CorsPolicy" />.</param> /// <returns> /// The <see cref="CorsResult" /> /// </returns> /// <exception cref="System.ArgumentNullException"> /// requestContext /// or /// policy /// </exception> public virtual CorsResult EvaluatePolicy(CorsRequestContext requestContext, CorsPolicy policy) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (policy == null) { throw new ArgumentNullException("policy"); } CorsResult result = new CorsResult(); if (!TryValidateOrigin(requestContext, policy, result)) { return(result); } result.SupportsCredentials = policy.SupportsCredentials; if (requestContext.IsPreflight) { if (!TryValidateMethod(requestContext, policy, result)) { return(result); } if (!TryValidateHeaders(requestContext, policy, result)) { return(result); } result.PreflightMaxAge = policy.PreflightMaxAge; } else { AddHeaderValues(result.AllowedExposedHeaders, policy.ExposedHeaders); } return(result); }
/// <summary> /// Evaluates the policy. /// </summary> /// <param name="requestContext">The <see cref="CorsRequestContext" />.</param> /// <param name="policy">The <see cref="CorsPolicy" />.</param> /// <returns> /// The <see cref="CorsResult" /> /// </returns> /// <exception cref="System.ArgumentNullException"> /// requestContext /// or /// policy /// </exception> public virtual CorsResult EvaluatePolicy(CorsRequestContext requestContext, CorsPolicy policy) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (policy == null) { throw new ArgumentNullException("policy"); } CorsResult result = new CorsResult(); if (!TryValidateOrigin(requestContext, policy, result)) { return result; } result.SupportsCredentials = policy.SupportsCredentials; if (requestContext.IsPreflight) { if (!TryValidateMethod(requestContext, policy, result)) { return result; } if (!TryValidateHeaders(requestContext, policy, result)) { return result; } result.PreflightMaxAge = policy.PreflightMaxAge; } else { AddHeaderValues(result.AllowedExposedHeaders, policy.ExposedHeaders); } return result; }
private CorsRequestContext GetCorsRequestContext( HttpRequestMessage request) { var origin = request.Headers.GetOrigin(); if (origin.IsNullOrEmpty()) return null; var context = new CorsRequestContext { RequestUri = request.RequestUri, HttpMethod = request.Method.ToString(), Host = request.Headers.Host, Origin = origin, AccessControlRequestMethod = request.Headers.GetAccessControlRequestMethod(), }; context.SetAccessControlRequestHeaders( request.Headers.GetAccessControlRequestHeaders()); return context; }
/// <summary> /// Try to validate the requested headers based on <see cref="CorsPolicy"/>. /// </summary> /// <param name="requestContext">The <see cref="CorsRequestContext"/>.</param> /// <param name="policy">The <see cref="CorsPolicy"/>.</param> /// <param name="result">The <see cref="CorsResult"/>.</param> /// <returns><c>true</c> if the requested headers are valid; otherwise, <c>false</c>. </returns> /// <exception cref="System.ArgumentNullException"> /// requestContext /// or /// policy /// or /// result /// </exception> public virtual bool TryValidateHeaders( CorsRequestContext requestContext, CorsPolicy policy, CorsResult result ) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (policy == null) { throw new ArgumentNullException("policy"); } if (result == null) { throw new ArgumentNullException("result"); } if ( policy.AllowAnyHeader || requestContext.AccessControlRequestHeaders.IsSubsetOf(policy.Headers) ) { AddHeaderValues(result.AllowedHeaders, requestContext.AccessControlRequestHeaders); } else { result.ErrorMessages.Add( String.Format( CultureInfo.CurrentCulture, SRResources.HeadersNotAllowed, String.Join(",", requestContext.AccessControlRequestHeaders) ) ); } return(result.IsValid); }
/// <summary> /// Try to validate the requested method based on <see cref="CorsPolicy"/>. /// </summary> /// <param name="requestContext">The <see cref="CorsRequestContext"/>.</param> /// <param name="policy">The <see cref="CorsPolicy"/>.</param> /// <param name="result">The <see cref="CorsResult"/>.</param> /// <returns><c>true</c> if the requested method is valid; otherwise, <c>false</c>. </returns> /// <exception cref="System.ArgumentNullException"> /// requestContext /// or /// policy /// or /// result /// </exception> public virtual bool TryValidateMethod( CorsRequestContext requestContext, CorsPolicy policy, CorsResult result ) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (policy == null) { throw new ArgumentNullException("policy"); } if (result == null) { throw new ArgumentNullException("result"); } if ( policy.AllowAnyMethod || policy.Methods.Contains(requestContext.AccessControlRequestMethod) ) { result.AllowedMethods.Add(requestContext.AccessControlRequestMethod); } else { result.ErrorMessages.Add( String.Format( CultureInfo.CurrentCulture, SRResources.MethodNotAllowed, requestContext.AccessControlRequestMethod ) ); } return(result.IsValid); }
public virtual bool TryValidateHeaders(CorsRequestContext requestContext, CorsPolicy policy, CorsResult result) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (policy == null) { throw new ArgumentNullException("policy"); } if (result == null) { throw new ArgumentNullException("result"); } if (policy.AllowAnyHeader || requestContext.AccessControlRequestHeaders.IsSubsetOf(policy.Headers)) { AddHeaderValues(result.AllowedHeaders, requestContext.AccessControlRequestHeaders); } else { result.ErrorMessages.Add(string.Format(CultureInfo.CurrentCulture, "The collection of headers '{0}' is not allowed.", new object[] { string.Join(",", requestContext.AccessControlRequestHeaders) })); } return(result.IsValid); }
private static CorsRequestContext GetCorsRequestContext(IOwinContext context) { string origin = context.Request.Headers.Get(CorsConstants.Origin); if (String.IsNullOrEmpty(origin)) { return null; } var requestContext = new CorsRequestContext { RequestUri = context.Request.Uri, HttpMethod = context.Request.Method, Host = context.Request.Host.Value, Origin = origin, AccessControlRequestMethod = context.Request.Headers.Get(CorsConstants.AccessControlRequestMethod) }; IList<string> headerValues = context.Request.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlRequestHeaders); if (headerValues != null) { foreach (var header in headerValues) { requestContext.AccessControlRequestHeaders.Add(header); } } return requestContext; }
private bool TryEvaluateCorsPolicy(CorsPolicy policy, CorsRequestContext corsRequestContext, out CorsResult result) { result = _corsEngine.EvaluatePolicy(corsRequestContext, policy); return result != null && result.IsValid; }
private void ProcessCors(OAuthValidateTokenRequestContext context) { var accessControlRequestMethodHeaders = context.Request.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlRequestMethod); var originHeaders = context.Request.Headers.GetCommaSeparatedValues(CorsConstants.Origin); var accessControlRequestHeaders = context.Request.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlRequestMethod); var corsRequest = new CorsRequestContext { Host = context.Request.Host.Value, HttpMethod = context.Request.Method, Origin = originHeaders == null ? null : originHeaders.FirstOrDefault(), RequestUri = context.Request.Uri, AccessControlRequestMethod = accessControlRequestMethodHeaders == null ? null : accessControlRequestMethodHeaders.FirstOrDefault() }; if (accessControlRequestHeaders != null) { foreach (var header in context.Request.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlRequestMethod)) { corsRequest.AccessControlRequestHeaders.Add(header); } } var engine = new CorsEngine(); if (corsRequest.IsPreflight) { try { // Make sure Access-Control-Request-Method is valid. var test = new HttpMethod(corsRequest.AccessControlRequestMethod); } catch (ArgumentException) { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; context.SetError("Access Control Request Method Cannot Be Null Or Empty"); //context.RequestCompleted(); return; } catch (FormatException) { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; context.SetError("Invalid Access Control Request Method"); //context.RequestCompleted(); return; } var result = engine.EvaluatePolicy(corsRequest, _options.CorsPolicy); if (!result.IsValid) { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; context.SetError(string.Join(" | ", result.ErrorMessages)); //context.RequestCompleted(); return; } WriteCorsHeaders(result, context); } else { var result = engine.EvaluatePolicy(corsRequest, _options.CorsPolicy); if (result.IsValid) { WriteCorsHeaders(result, context); } } }
/// <summary> /// Handles the preflight request specified by CORS. /// </summary> /// <param name="request">The request.</param> /// <param name="corsRequestContext">The cors request context.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The <see cref="Task{HttpResponseMessage}"/></returns> /// <exception cref="System.ArgumentNullException"> /// request /// or /// corsRequestContext /// </exception> public virtual async Task<HttpResponseMessage> HandleCorsPreflightRequestAsync(HttpRequestMessage request, CorsRequestContext corsRequestContext, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException("request"); } if (corsRequestContext == null) { throw new ArgumentNullException("corsRequestContext"); } try { // Make sure Access-Control-Request-Method is valid. new HttpMethod(corsRequestContext.AccessControlRequestMethod); } catch (ArgumentException) { return request.CreateErrorResponse(HttpStatusCode.BadRequest, SRResources.AccessControlRequestMethodCannotBeNullOrEmpty); } catch (FormatException) { return request.CreateErrorResponse(HttpStatusCode.BadRequest, String.Format(CultureInfo.CurrentCulture, SRResources.InvalidAccessControlRequestMethod, corsRequestContext.AccessControlRequestMethod)); } CorsPolicy corsPolicy = await GetCorsPolicyAsync(request, cancellationToken); if (corsPolicy != null) { HttpResponseMessage response = null; CorsResult result; if (TryEvaluateCorsPolicy(corsRequestContext, corsPolicy, out result)) { response = request.CreateResponse(HttpStatusCode.OK); response.WriteCorsHeaders(result); } else { response = result != null ? request.CreateErrorResponse(HttpStatusCode.BadRequest, String.Join(" | ", result.ErrorMessages)) : request.CreateResponse(HttpStatusCode.BadRequest); } return response; } else { return await base.SendAsync(request, cancellationToken); } }
private bool TryEvaluateCorsPolicy(CorsRequestContext requestContext, CorsPolicy corsPolicy, out CorsResult corsResult) { ICorsEngine engine = _httpConfiguration.GetCorsEngine(); corsResult = engine.EvaluatePolicy(requestContext, corsPolicy); return corsResult != null && corsResult.IsValid; }
/// <summary> /// Handles the preflight request specified by CORS. /// </summary> /// <param name="request">The request.</param> /// <param name="corsRequestContext">The cors request context.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The <see cref="Task{HttpResponseMessage}"/></returns> /// <exception cref="System.ArgumentNullException"> /// request /// or /// corsRequestContext /// </exception> public virtual async Task<HttpResponseMessage> HandleCorsPreflightRequestAsync(HttpRequestMessage request, CorsRequestContext corsRequestContext, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (request == null) { throw new ArgumentNullException("request"); } if (corsRequestContext == null) { throw new ArgumentNullException("corsRequestContext"); } CorsPolicy corsPolicy = await GetCorsPolicyAsync(request); if (corsPolicy != null) { HttpResponseMessage response = null; CorsResult result; if (TryEvaluateCorsPolicy(corsRequestContext, corsPolicy, out result)) { response = request.CreateResponse(HttpStatusCode.OK); response.WriteCorsHeaders(result); } else { response = result != null ? request.CreateErrorResponse(HttpStatusCode.BadRequest, String.Join(" | ", result.ErrorMessages)) : request.CreateResponse(HttpStatusCode.BadRequest); } return response; } else { return await base.SendAsync(request, cancellationToken); } }
private Task<HttpResponseMessage> HandleCorsRequest( HttpRequestMessage request, CancellationToken cancellationToken, CorsRequestContext corsRequestContext) { if (corsRequestContext.IsPreflight) return HandleCorsPreflightRequest(corsRequestContext); return base.Handle(request, cancellationToken) .ContinueWith(responseTask => { var response = responseTask.Result; WriteCorsHeaders(response, corsRequestContext); return response; }); }
private void WriteCorsHeaders( HttpResponseMessage response, CorsRequestContext corsRequestContext) { var headers = _corsEngineFactory() .GetCorsResponseHeaders(corsRequestContext, Options); foreach (var header in headers) response.Headers.Add(header.Key, header.Value); }
private Task<HttpResponseMessage> HandleCorsPreflightRequest( CorsRequestContext corsRequestContext) { var response = new HttpResponseMessage(HttpStatusCode.OK); WriteCorsHeaders(response, corsRequestContext); return Task.FromResult(response); }
/// <summary> /// Try to validate the requested headers based on <see cref="CorsPolicy"/>. /// </summary> /// <param name="requestContext">The <see cref="CorsRequestContext"/>.</param> /// <param name="policy">The <see cref="CorsPolicy"/>.</param> /// <param name="result">The <see cref="CorsResult"/>.</param> /// <returns><c>true</c> if the requested headers are valid; otherwise, <c>false</c>. </returns> /// <exception cref="System.ArgumentNullException"> /// requestContext /// or /// policy /// or /// result /// </exception> public virtual bool TryValidateHeaders(CorsRequestContext requestContext, CorsPolicy policy, CorsResult result) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (policy == null) { throw new ArgumentNullException("policy"); } if (result == null) { throw new ArgumentNullException("result"); } if (policy.AllowAnyHeader || requestContext.AccessControlRequestHeaders.IsSubsetOf(policy.Headers)) { AddHeaderValues(result.AllowedHeaders, requestContext.AccessControlRequestHeaders); } else { result.ErrorMessages.Add(String.Format( CultureInfo.CurrentCulture, SRResources.HeadersNotAllowed, String.Join(",", requestContext.AccessControlRequestHeaders))); } return result.IsValid; }
/// <summary> /// Try to validate the request origin based on <see cref="CorsPolicy"/>. /// </summary> /// <param name="requestContext">The <see cref="CorsRequestContext"/>.</param> /// <param name="policy">The <see cref="CorsPolicy"/>.</param> /// <param name="result">The <see cref="CorsResult"/>.</param> /// <returns><c>true</c> if the request origin is valid; otherwise, <c>false</c>. </returns> /// <exception cref="System.ArgumentNullException"> /// requestContext /// or /// policy /// or /// result /// </exception> public virtual bool TryValidateOrigin(CorsRequestContext requestContext, CorsPolicy policy, CorsResult result) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (policy == null) { throw new ArgumentNullException("policy"); } if (result == null) { throw new ArgumentNullException("result"); } if (requestContext.Origin != null) { if (policy.AllowAnyOrigin) { if (policy.SupportsCredentials) { result.AllowedOrigin = requestContext.Origin; } else { result.AllowedOrigin = CorsConstants.AnyOrigin; } } else if (policy.Origins.Contains(requestContext.Origin)) { result.AllowedOrigin = requestContext.Origin; } else { result.ErrorMessages.Add(String.Format( CultureInfo.CurrentCulture, SRResources.OriginNotAllowed, requestContext.Origin)); } } else { result.ErrorMessages.Add(SRResources.NoOriginHeader); } return result.IsValid; }