I have a requirement to allow users to change their passwords via a form in my asp.net MVC application. My first thought was to decorate the ChangePassword action with a RequireHttps attribute.
However, I still have to send the password unencrypted before the attribute kicks in and returns "The requested resource can only be accessed via SSL". This defeats the purpose, doesn't it?
I am sure I am just confused and RequireHttps is useful; I would like to know if there is a way to use RequireHttps to achieve my aim. Alternatively, I would like to know any other way to achieve it.
UPDATE:
I now have some options thanks to the answers below - I can load the password inputs in an iframe using https, meaning that any posts from it will be encrypted. Other wise I can set the protocol to https in the code that constructs the post url:
var url = '@Url.Action("changePassword", "Security", new { area = "" }, "https")'
I'm not sure which is better, but I'm going to try the second one - any comments welcome.
Your application cannot control whether SSL is enabled. This depends only on web server configuration. The only thing you can do is make sure your application does not trust data that was not encrypted on the wire. RequireHttps does just that. Actions decorated with this attribute will never processes data that was sent in plain text.
The real use case of the RequireHttpsAttribute is to enforce the https:// scheme only when authentication is requested. Not in all cases. The RequireHttpsAttribute only implements the OnAuthentication method of the IAuthenticationFilter interface.
As the OnAuthentication method is only called from within the InvokeAuthenticationFilters method, I wouldn't use the RequireHttpsAttribute attribute.
To properly enforce https:// on certain controllers or actions, I'd create my own attribute, based on ActionFilterAttribute:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class EnforceHttpsActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (new[] { "GET", "HEAD" }.Any(verb => String.Equals(filterContext.HttpContext.Request.HttpMethod, verb, StringComparison.OrdinalIgnoreCase))) ;
{
string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
filterContext.Result = new RedirectResult(url);
}
}
}
To enforce https:// for the whole site, you can get inspired by a web.config markup that I've used for *.azurewebsites.net instances of our sample app.
<system.webServer>
<rewrite>
<rules>
<rule name="HTTPS Redirect in Azure">
<match url="(.+)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{HTTP_HOST}" pattern="^(.+)\.azurewebsites.net(.*)$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="SeeOther" />
</rule>
</rules>
</rewrite>
</system.webServer>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With