Forcing SSL (https) on a page by page basis - c#

How can I set up my page load event in my code behind to redirect to an url that has an https prefix? I would need it to work with urls that have query strings attached too.
It's one thing to construct a link that goes straight to the https page, but I don't want the user to be able to manually change it to an http page.
Also I don't want to do it with javascript because it might be turned off.
I'm guessing a regular expression?

We mark our SSL Required pages with a special attribute ForceSslAttribute. Then we have a HttpModule that pulls down the current page's class and inspect it's attributes.
If the attribute is present on the page, it takes the exact url that was passed and changes the protocol from http to https then calls a redirect.
There's probably a bit simpler way of doing it, but that's how it's done for us.
Attribute:
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public sealed class ForceSslAttribute : Attribute
{
// Marker Attribute
}
Page Example (CodeBehind):
[ForceSsl]
public partial class User_Login : Page
{
//...
}
You can figure out the type of the page like this:
HttpContext.Current.CurrentHandler.GetType()
All Page's implement IHttpHandler and when you're visiting a page, it'll work.
The cool part about this method is you can mark anything that's an IHttpHandler and it'll force the redirect too :)

Add this at the top of your Page_Load
if (Request.ServerVariables["HTTPS"] != "ON")
{
Response.Redirect("https://" + Request["HTTP_HOST"] + Request.RawUrl);
}

I use the following in Global.asax Application_BeginRequest
If needsSSL <> Request.IsSecureConnection Then
If needsSSL Then
Response.Redirect(Uri.UriSchemeHttps + Uri.SchemeDelimiter + Request.Url.Host + Request.Url.PathAndQuery, True)
Else
Response.Redirect(Uri.UriSchemeHttp + Uri.SchemeDelimiter + Request.Url.Host + Request.Url.PathAndQuery, True)
End If
End If

There is an IIS7 module for URL rewriting. Very handy, but you need access to the IIS and it requires some time to learn how to write the rules. A simple http->https rule is a matter of seconds.
Just be careful because any rules you add will be stored in your web.config, so don't delete/override it or you will have to write them again.

Forcing SSL using ASP
To force SSL using ASP, follow these steps:
Click Start, click Run, type Notepad, and then click OK.
Paste the following code into a blank Notepad document. On the File menu, click Save As, and then save the following code in the root of your Web server as an include file named ForceSSL.inc:
<%
If Request.ServerVariables("SERVER_PORT")=80 Then
Dim strSecureURL
strSecureURL = "https://"
strSecureURL = strSecureURL & Request.ServerVariables("SERVER_NAME")
strSecureURL = strSecureURL & Request.ServerVariables("URL")
Response.Redirect strSecureURL
End If
%>
For each page that requires SSL, paste the following code at the top of the page to reference the include file from the previous step:
<%#Language="VBSCRIPT"%>
<!--#include virtual="/ForceSSL.inc"-->
When each page is browsed, the ASP code that is contained in the include file detects the port to determine if HTTP is used. If HTTP is used, the browser will be redirected to the same page by using HTTPS.

Related

ASP.NET with IIS url rewrite on language change

I have imprelemnted a complex url rewrite to translate user frendly url into internal application url.
So basically if you go to my site (an ecommerce) :
"https://some_domain/en/shoes/some_brand/article-description-written-in-a-firendly-manner_articleCode"
Then the url is rewritten into the internal version "https://some_domain/Products.aspx?id=articleCode&languageCode=en"
The viceversa also is true, when an internal URL need to be produced and placed into the page, it's rewritten into it's "external" shape.
Everything work just fine, until someone will change the language (eg : from 'en' to 'de').
Language change like many other parameter change is applied on query string, so changing language will trigger a page refresh with the trailing parameter into query string.
So 'en' to 'de' in the previous url will casue the following call :
"https://some_domain/en/shoes/some_brand/article-description-written-in-a-firendly-manner_articleCode?languageCode=de"
Then even if server-side i consider the language to be german, how i can rewrite the url displaied into the browser?
It should become something similar to :
"https://some_domain/de/schuhe/some_brand/artikelbeschreibung-freundlich-geschrieben_articleCode"
Should i calculate the new external URL and do a 302 redirect (HttpResponse.Redirect)?
Or is a better option put the precalculated url as link in the language change button?

Redirecting user to external site

I want to redirect a user to an external site, outside of my ASP.NET MVC application, through a simple anchor tag. The tricky part is, the user can enter the link himself.
up up and away!
If the user enters: www.google.com in a field (bad user), he is being redirected to http://www.example.com/page/www.google.com.
which is totally understandable, he should use http:// in front of his link...
It works as expected if I hardcode the http://in front of the link like so: up up and away!
BUT if the user was to enter http://www.google.com (good user), the browser redirects to http://http//www.google.com which goes nowhere..
So now the question: Is there a helper or method or something that routes to an external site no matter if the link contains http://or not? Something like #Url.ExternalLink(model.Url) would be great.
I could write this myself, but no need to reinvent the wheel, right? So if the wheel exists, please provide the wheel! Thanks in advance!
Checked a bunch of links, but they didn't satisfy my needs of the variable user input (never trust a user!):
How to properly encode links to external URL in MVC Razor ,
Redirect to external url from OnActionExecuting? ,
Why does Response.Redirect not redirect external URL? ,
url.Action open link in new window on ASP.NET MVC Page , ...
Your use case is quite specific, MVC framework doesn't have any extension methods for this.
You need to develop it by yourself. You have the following options:
Create extension method (as you mentioned) for UrlHelper class - #Url.ExternalLink(model.Url)
Create extension method for HtmlHelper - #Html.ExternalLinkFor(model => model.Url)
As url comes from your model you can validate/modify it before passing to View. In this case up up and away! will still be valid.
Add regex validator to a View where user types in url
You can easily extend UrlHelper with a method:
public static string ExternalLink(this UrlHelper helper, string uri)
{
if (uri.StartsWith("http://")) return uri;
return string.Format("http://{0}", uri);
}
Examples
#Url.ExternalLink("http://google.com")
#Url.ExternalLink("google.com")

MVC3 deploy to a directory, url issue

I have a mvc3 web application which will be delopyed to an directory of a website. the address of the application seems like http://wwww.xx.com/aopo/. aopo is the name of the directory. After the deployement I find that the url in js file does not work any more. because I had write the js code with hard code url, just like
$.ajax({url:"/employee/getemployee"})
In that case the request will be sent to http://wwww.xx.com/employee/getemployee instead of http://wwww.xx.com/aopo/employee/getemployee, and 404 is returned.
There is lots of code in js like that. I don't want to modify the js. Is there any simple approach to make it work? Can I rewrite the request in global.asax.cs?
I believe you'll need to change your url references to this:
$.ajax({url:"#Url.Action("getemplotee","employee")"})
If this is a script file you can write the correct URL into an element on the page and read that:
<div id='Main' data-url='#Url.Action("getemplotee","employee")' />
Then in your script:
$.ajax({url:$('#Main').data('url')})
Rgarding:
There is lots of code in js like that. I don't want to modify the js
I understand, but you need to use the proper helper methods to account for running under virtual directories, so I would recommending biting the bullet and just fixing it the right way.
One not so clean solution might be,
Setting a url prefix in the layout(in a common place), like
<script type="text/javascript">
#{
string root = Url.Content("~/");
if (root.EndsWith("/", StringComparison.Ordinal))
{
root = root.Substring(0, root.Length - 1);
}
}
window.URL_PREFIX = '#root';
</script>
then use the prefix in the ajaxSend hook and change the url.
$(document).ajaxSend(function (event, jqxhr, settings) {
if (window.URL_PREFIX && settings.url.indexOf(window.URL_PREFIX)) {
settings.url = window.URL_PREFIX + settings.url;
}
});
note: If $.ajax() or $.ajaxSetup() is called with the global option set to false, the .ajaxSend() method will not fire.
its not an ideal solution, but might be helpful in a tight situation.
hope this helps.
No, that's not possible. Since the request doesn't arrive in your application you can't access it and thus you can't rewrite it.
If you have control over the root site, you could use the IIS rewrite module to rewrite the URL to your website.

how should I store my dynamic css file name within the current session

I'm not sure how to ask this directly so I'll explain my situation.
We have a portal for our clients and they access the site as such:
http://url.com/webporta/{their guid}/
The guid determines what css file gets loaded for the site:
<link href="#Url.Content(string.Format("~/Content/{0}.css", GetCookieInfo.CssFile))" rel="stylesheet" type="text/css" />
I am reading the css file name and repopulating the cookie EVERY time they visit the site just to make sure I have the current value.
This is where I am reading the database from a service call and writing out the cookie:
var css = client.GetCssFile(id);
if (string.IsNullOrEmpty(css))
{
sb.AppendLine("Setting css to 'Site' default since GetCssFile returned null or empty.");
css = "Site";
}
and the method that is called to write it:
var httpCookie4 = HttpContext.Current.Request.Cookies.Get(CookieEnums.CssFile.ToString());
return httpCookie4 != null ? httpCookie4.Value : "Site";
This works fine until they visit with a different guid. They only way for it to 'reread' the cookie is to CTRL-F5 to force a refresh of the page.
There has got to be a better way than this since I cannot seem to get the site to reread the cookies at load time, or at least I don't know how to.
Any suggestions on a better way of handling this?
========== EDIT #1 ===========
I tried session originally but had an issue with it timing out. I was also suggested to use cookies on this post: How reliant should I be on Session
ErocM here is something that you can also try
do you know how to set / adjust Session Timeout? if not do the following
to change session timeout write this code in your web.config file
or you can also set this in global.asax file as Session.Timeout = 60;
// in Session.Start() event it will increase your session expire time .
Instead of storing the CSS file name in the cookie, have a controller or http handler decide which CSS file to serve based on the GUID.
So the URL would be something like http://url.com/whatever/GetCSS/{GUID}. When they visit a site with a different GUID, the response changes to the appropriate CSS file for that GUID.

Redirecting webpage in ASP.NET depending on the URL

I've a domain name called mywebsite.com but I prefer users to access to my website through the www subdomain.
How can I achieve a verification and redirection in asp.net mvc3 easily?
When I was using php I did something like that :
if($_SERVER['SERVER_NAME'] != "www.mywebsite.com")
header('Location: www.mywebsite.com');
I'd like to find a similar way to achieve this kind of redirection in asp.net (C#) (I'd prefer not to set a 301 redirection but just a soft redirection like the one I was using in PHP).
I know I could do a verification in each of my controllers action methods and the redirect the user if he is not on the subdomain www.mywebsite.com but I'd prefer to write once the verification and the redirection and I can't find where :/
Thanks a lot !
You could use:
Request.Url.ToString()
This will return the URL , then you can quickly check if it contains 'www.' and redirect if true. However I would suggest that your handle this in the URL rewrite in IIS.
Follow the guide here: http://www.dotnetexpertguide.com/2011/08/iis-7-redirect-domaincom-to.html this is for making domain.com go to www.domain.com, but it works the same way for the opposite.
you could try something like this
if(!Request.Url.Host.Equals("www.mywebsite.com"))
{
Response.Redirect("website");
}
If you are looking to just add/append header information, then use Response.AppendHeader().
The Request.Url.ToString() property can be checked for the url you are looking for as per Ryan's answer.
Actually, the original question asks specifically for a 'soft' redirection (201 or 202) instead of a Moved Permanently/Found (301/302), so i think that instead of Response.Redirect the conditional line should be:
if(!Request.Url.Host.Equals("www.mywebsite.com"))
{
HttpContext.Current.Response.Headers.Add("Location", "www.mywebsite.com");
}
EDIT: I believe the status may also be set directly, used in conjunction with Response.Redirect:
if(!Request.Url.Host.Equals("www.mywebsite.com"))
{
HttpContext.Current.Response.Redirect("www.mywebsite.com");
HttpContext.Current.Response.Status = "201 Created";
}
If I am not totally missing something here, can't you just setup the host-header in the IIS settings for the site to include both www.domain.com as well as domain.com?

Categories

Resources