parent
f7e95751d8
commit
be5deef584
|
|
@ -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.
|
/// is used. If not set the port won't be specified in the secured URL e.g. https://localhost/path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? SslPort { get; set; }
|
public int? SslPort { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default value for the Permanent property of <see cref="RequireHttpsAttribute"/>.
|
||||||
|
/// </summary>
|
||||||
|
public bool RequireHttpsPermanent { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -15,11 +15,17 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
|
||||||
public class RequireHttpsAttribute : Attribute, IAuthorizationFilter, IOrderedFilter
|
public class RequireHttpsAttribute : Attribute, IAuthorizationFilter, IOrderedFilter
|
||||||
{
|
{
|
||||||
|
private bool? _permanent;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifies whether a permanent redirect, <c>301 Moved Permanently</c>,
|
/// Specifies whether a permanent redirect, <c>301 Moved Permanently</c>,
|
||||||
/// should be used instead of a temporary redirect, <c>302 Found</c>.
|
/// should be used instead of a temporary redirect, <c>302 Found</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Permanent { get; set; }
|
public bool Permanent
|
||||||
|
{
|
||||||
|
get { return _permanent ?? false; }
|
||||||
|
set { _permanent = value; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
@ -82,6 +88,8 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
host = new HostString(host.Host);
|
host = new HostString(host.Host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var permanentValue = _permanent ?? optionsAccessor.Value.RequireHttpsPermanent;
|
||||||
|
|
||||||
var newUrl = string.Concat(
|
var newUrl = string.Concat(
|
||||||
"https://",
|
"https://",
|
||||||
host.ToUriComponent(),
|
host.ToUriComponent(),
|
||||||
|
|
@ -90,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
request.QueryString.ToUriComponent());
|
request.QueryString.ToUriComponent());
|
||||||
|
|
||||||
// redirect to HTTPS version of page
|
// redirect to HTTPS version of page
|
||||||
filterContext.Result = new RedirectResult(newUrl, Permanent);
|
filterContext.Result = new RedirectResult(newUrl, permanentValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,24 +192,30 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(true)]
|
[InlineData(null, true)]
|
||||||
[InlineData(false)]
|
[InlineData(null, false)]
|
||||||
public void OnAuthorization_RedirectsToHttpsEndpoint_WithSpecifiedStatusCode(bool permanent)
|
[InlineData(true, false)]
|
||||||
|
[InlineData(false, true)]
|
||||||
|
public void OnAuthorization_RedirectsToHttpsEndpoint_WithSpecifiedStatusCodeAndrequireHttpsPermanentOption(bool? permanent, bool requireHttpsPermanent)
|
||||||
{
|
{
|
||||||
var requestContext = new DefaultHttpContext();
|
var requestContext = new DefaultHttpContext();
|
||||||
requestContext.RequestServices = CreateServices();
|
requestContext.RequestServices = CreateServices(null, requireHttpsPermanent);
|
||||||
requestContext.Request.Scheme = "http";
|
requestContext.Request.Scheme = "http";
|
||||||
requestContext.Request.Method = "GET";
|
requestContext.Request.Method = "GET";
|
||||||
|
|
||||||
var authContext = CreateAuthorizationContext(requestContext);
|
var authContext = CreateAuthorizationContext(requestContext);
|
||||||
var attr = new RequireHttpsAttribute { Permanent = permanent };
|
var attr = new RequireHttpsAttribute();
|
||||||
|
if (permanent.HasValue)
|
||||||
|
{
|
||||||
|
attr.Permanent = permanent.Value;
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
attr.OnAuthorization(authContext);
|
attr.OnAuthorization(authContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var result = Assert.IsType<RedirectResult>(authContext.Result);
|
var result = Assert.IsType<RedirectResult>(authContext.Result);
|
||||||
Assert.Equal(permanent, result.Permanent);
|
Assert.Equal(permanent ?? requireHttpsPermanent, result.Permanent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CustomRequireHttpsAttribute : RequireHttpsAttribute
|
private class CustomRequireHttpsAttribute : RequireHttpsAttribute
|
||||||
|
|
@ -226,10 +232,11 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
return new AuthorizationFilterContext(actionContext, new IFilterMetadata[0]);
|
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<MvcOptions>();
|
var options = new TestOptionsManager<MvcOptions>();
|
||||||
options.Value.SslPort = sslPort;
|
options.Value.SslPort = sslPort;
|
||||||
|
options.Value.RequireHttpsPermanent = requireHttpsPermanent;
|
||||||
|
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.AddSingleton<IOptions<MvcOptions>>(options);
|
services.AddSingleton<IOptions<MvcOptions>>(options);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue