Added logging for preflight requests and origin headers

This commit is contained in:
Jass Bagga 2016-11-15 10:28:06 -08:00
parent de383b7ee4
commit 4de03b6dff
3 changed files with 76 additions and 1 deletions

View File

@ -5,9 +5,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Cors.Internal;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Cors.Infrastructure namespace Microsoft.AspNetCore.Cors.Infrastructure
{ {
@ -17,12 +19,23 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
public class CorsService : ICorsService public class CorsService : ICorsService
{ {
private readonly CorsOptions _options; private readonly CorsOptions _options;
private readonly ILogger _logger;
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="CorsService"/>. /// Creates a new instance of the <see cref="CorsService"/>.
/// </summary> /// </summary>
/// <param name="options">The option model representing <see cref="CorsOptions"/>.</param> /// <param name="options">The option model representing <see cref="CorsOptions"/>.</param>
public CorsService(IOptions<CorsOptions> options) public CorsService(IOptions<CorsOptions> options)
:this(options, loggerFactory: null)
{
}
/// <summary>
/// Creates a new instance of the <see cref="CorsService"/>.
/// </summary>
/// <param name="options">The option model representing <see cref="CorsOptions"/>.</param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
public CorsService(IOptions<CorsOptions> options, ILoggerFactory loggerFactory)
{ {
if (options == null) if (options == null)
{ {
@ -30,6 +43,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
} }
_options = options.Value; _options = options.Value;
_logger = loggerFactory?.CreateLogger<CorsService>();
} }
/// <summary> /// <summary>
@ -70,6 +84,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
!StringValues.IsNullOrEmpty(accessControlRequestMethod)) !StringValues.IsNullOrEmpty(accessControlRequestMethod))
{ {
EvaluatePreflightRequest(context, policy, corsResult); EvaluatePreflightRequest(context, policy, corsResult);
_logger?.IsPreflightRequest();
} }
else else
{ {
@ -87,6 +102,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
return; return;
} }
_logger?.RequestHasOriginHeader();
AddOriginToResult(origin, policy, result); AddOriginToResult(origin, policy, result);
result.SupportsCredentials = policy.SupportsCredentials; result.SupportsCredentials = policy.SupportsCredentials;
AddHeaderValues(result.AllowedExposedHeaders, policy.ExposedHeaders); AddHeaderValues(result.AllowedExposedHeaders, policy.ExposedHeaders);
@ -100,6 +116,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
return; return;
} }
_logger?.RequestHasOriginHeader();
var accessControlRequestMethod = context.Request.Headers[CorsConstants.AccessControlRequestMethod]; var accessControlRequestMethod = context.Request.Headers[CorsConstants.AccessControlRequestMethod];
if (StringValues.IsNullOrEmpty(accessControlRequestMethod)) if (StringValues.IsNullOrEmpty(accessControlRequestMethod))
{ {

View File

@ -0,0 +1,58 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Cors.Internal
{
internal static class CORSLoggerExtensions
{
private static readonly Action<ILogger, Exception> _isPreflightRequest;
private static readonly Action<ILogger, Exception> _requestHasOriginHeader;
private static readonly Action<ILogger, Exception> _policySuccess;
private static readonly Action<ILogger, string, Exception> _policyFailure;
static CORSLoggerExtensions()
{
_isPreflightRequest = LoggerMessage.Define(
LogLevel.Debug,
1,
"The request is preflight.");
_requestHasOriginHeader = LoggerMessage.Define(
LogLevel.Debug,
2,
"The request has an origin header.");
_policySuccess = LoggerMessage.Define(
LogLevel.Information,
3,
"Policy execution successful.");
_policyFailure = LoggerMessage.Define<string>(
LogLevel.Information,
3,
"Policy execution failed. '{FailureReason}'");
}
public static void IsPreflightRequest(this ILogger logger)
{
_isPreflightRequest(logger, null);
}
public static void RequestHasOriginHeader(this ILogger logger)
{
_requestHasOriginHeader(logger, null);
}
public static void PolicySuccess(this ILogger logger, string failureReason)
{
_policySuccess(logger, null);
}
public static void PolicyFailure(this ILogger logger, string failureReason)
{
_policyFailure(logger, failureReason, null);
}
}
}

View File

@ -446,7 +446,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
} }
[Fact] [Fact]
public void EaluatePolicy_DoesCaseSensitiveComparison() public void EvaluatePolicy_DoesCaseSensitiveComparison()
{ {
// Arrange // Arrange
var corsService = new CorsService(new TestCorsOptions()); var corsService = new CorsService(new TestCorsOptions());