Browse Source

Add `AbpSecurityHeadersOptions`.

Resolve #14173
pull/14274/head
maliming 4 years ago
parent
commit
c8584b8087
  1. 17
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs
  2. 8
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersOptions.cs
  3. 15
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Security/Headers/SecurityHeadersTestController_Tests.cs

17
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Volo.Abp.DependencyInjection;
@ -8,6 +10,13 @@ namespace Volo.Abp.AspNetCore.Security;
public class AbpSecurityHeadersMiddleware : IMiddleware, ITransientDependency
{
public IOptions<AbpSecurityHeadersOptions> Options { get; set; }
public AbpSecurityHeadersMiddleware(IOptions<AbpSecurityHeadersOptions> options)
{
Options = options;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
/*X-Content-Type-Options header tells the browser to not try and “guess” what a mimetype of a resource might be, and to just take what mimetype the server has returned as fact.*/
@ -22,6 +31,14 @@ public class AbpSecurityHeadersMiddleware : IMiddleware, ITransientDependency
/*The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should be followed and not be changed. The header allows you to avoid MIME type sniffing by saying that the MIME types are deliberately configured.*/
AddHeaderIfNotExists(context, "X-Content-Type-Options", "nosniff");
if (Options.Value.UseContentSecurityPolicyHeader)
{
AddHeaderIfNotExists(context, "Content-Security-Policy",
Options.Value.ContentSecurityPolicyValue.IsNullOrEmpty()
? "object-src 'none'; form-action 'self'; frame-ancestors 'none'"
: Options.Value.ContentSecurityPolicyValue);
}
await next.Invoke(context);
}

8
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersOptions.cs

@ -0,0 +1,8 @@
namespace Volo.Abp.AspNetCore.Security;
public class AbpSecurityHeadersOptions
{
public bool UseContentSecurityPolicyHeader { get; set; }
public string ContentSecurityPolicyValue { get; set; }
}

15
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Security/Headers/SecurityHeadersTestController_Tests.cs

@ -1,12 +1,25 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Shouldly;
using Volo.Abp.AspNetCore.Security;
using Xunit;
namespace Volo.Abp.AspNetCore.Mvc.Security.Headers;
public class SecurityHeadersTestController_Tests : AspNetCoreMvcTestBase
{
protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services)
{
services.Configure<AbpSecurityHeadersOptions>(options =>
{
options.UseContentSecurityPolicyHeader = true;
});
base.ConfigureServices(context, services);
}
[Fact]
public async Task SecurityHeaders_Should_Be_Added()
{
@ -14,5 +27,7 @@ public class SecurityHeadersTestController_Tests : AspNetCoreMvcTestBase
responseMessage.Headers.ShouldContain(x => x.Key == "X-Content-Type-Options" & x.Value.First().ToString() == "nosniff");
responseMessage.Headers.ShouldContain(x => x.Key == "X-XSS-Protection" & x.Value.First().ToString() == "1; mode=block");
responseMessage.Headers.ShouldContain(x => x.Key == "X-Frame-Options" & x.Value.First().ToString() == "SAMEORIGIN");
responseMessage.Headers.ShouldContain(x => x.Key == "X-Content-Type-Options" & x.Value.First().ToString() == "nosniff");
responseMessage.Headers.ShouldContain(x => x.Key == "Content-Security-Policy" & x.Value.First().ToString() == "object-src 'none'; form-action 'self'; frame-ancestors 'none'");
}
}

Loading…
Cancel
Save