From be5deef58403618b824258b63c96fc86d9662e38 Mon Sep 17 00:00:00 2001 From: ivano scifoni Date: Thu, 4 Aug 2016 20:43:16 +0200 Subject: [PATCH] Created option for RequireHttpsAttribute.Permanent Fixes #4650 --- .../MvcOptions.cs | 5 +++++ .../RequireHttpsAttribute.cs | 12 +++++++++-- .../RequireHttpsAttributeTests.cs | 21 ++++++++++++------- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/MvcOptions.cs b/src/Microsoft.AspNetCore.Mvc.Core/MvcOptions.cs index b314d360d3..0b0165362e 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/MvcOptions.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/MvcOptions.cs @@ -140,5 +140,10 @@ namespace Microsoft.AspNetCore.Mvc /// is used. If not set the port won't be specified in the secured URL e.g. https://localhost/path. /// public int? SslPort { get; set; } + + /// + /// Gets or sets the default value for the Permanent property of . + /// + public bool RequireHttpsPermanent { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Mvc.Core/RequireHttpsAttribute.cs b/src/Microsoft.AspNetCore.Mvc.Core/RequireHttpsAttribute.cs index b3c34a1a96..89316991dc 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/RequireHttpsAttribute.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/RequireHttpsAttribute.cs @@ -15,11 +15,17 @@ namespace Microsoft.AspNetCore.Mvc [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class RequireHttpsAttribute : Attribute, IAuthorizationFilter, IOrderedFilter { + private bool? _permanent; + /// /// Specifies whether a permanent redirect, 301 Moved Permanently, /// should be used instead of a temporary redirect, 302 Found. /// - public bool Permanent { get; set; } + public bool Permanent + { + get { return _permanent ?? false; } + set { _permanent = value; } + } /// public int Order { get; set; } @@ -82,6 +88,8 @@ namespace Microsoft.AspNetCore.Mvc host = new HostString(host.Host); } + var permanentValue = _permanent ?? optionsAccessor.Value.RequireHttpsPermanent; + var newUrl = string.Concat( "https://", host.ToUriComponent(), @@ -90,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc request.QueryString.ToUriComponent()); // redirect to HTTPS version of page - filterContext.Result = new RedirectResult(newUrl, Permanent); + filterContext.Result = new RedirectResult(newUrl, permanentValue); } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/RequireHttpsAttributeTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/RequireHttpsAttributeTests.cs index 1480c9102d..e28b08f6fe 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/RequireHttpsAttributeTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/RequireHttpsAttributeTests.cs @@ -192,24 +192,30 @@ namespace Microsoft.AspNetCore.Mvc } [Theory] - [InlineData(true)] - [InlineData(false)] - public void OnAuthorization_RedirectsToHttpsEndpoint_WithSpecifiedStatusCode(bool permanent) + [InlineData(null, true)] + [InlineData(null, false)] + [InlineData(true, false)] + [InlineData(false, true)] + public void OnAuthorization_RedirectsToHttpsEndpoint_WithSpecifiedStatusCodeAndrequireHttpsPermanentOption(bool? permanent, bool requireHttpsPermanent) { var requestContext = new DefaultHttpContext(); - requestContext.RequestServices = CreateServices(); + requestContext.RequestServices = CreateServices(null, requireHttpsPermanent); requestContext.Request.Scheme = "http"; requestContext.Request.Method = "GET"; var authContext = CreateAuthorizationContext(requestContext); - var attr = new RequireHttpsAttribute { Permanent = permanent }; + var attr = new RequireHttpsAttribute(); + if (permanent.HasValue) + { + attr.Permanent = permanent.Value; + }; // Act attr.OnAuthorization(authContext); // Assert var result = Assert.IsType(authContext.Result); - Assert.Equal(permanent, result.Permanent); + Assert.Equal(permanent ?? requireHttpsPermanent, result.Permanent); } private class CustomRequireHttpsAttribute : RequireHttpsAttribute @@ -226,10 +232,11 @@ namespace Microsoft.AspNetCore.Mvc return new AuthorizationFilterContext(actionContext, new IFilterMetadata[0]); } - private static IServiceProvider CreateServices(int? sslPort = null) + private static IServiceProvider CreateServices(int? sslPort = null, bool requireHttpsPermanent = false) { var options = new TestOptionsManager(); options.Value.SslPort = sslPort; + options.Value.RequireHttpsPermanent = requireHttpsPermanent; var services = new ServiceCollection(); services.AddSingleton>(options);