Setting cookie doesn't persist between web requests - asp.net

I've created a brand new ASP.Net 4.6 MVC project, and have tried to set a value in the Requests Cookies collection and retrieve it in the next request. I'm using cookies because Session isn't available yet within the Application_BeginRequest method. Using the following code, the cookie value I ask for is null in every request I make, despite setting it.
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_BeginRequest()
{
var cookie = this.Request.Cookies.Get("Foo");
string value = cookie?.Value;
if (string.IsNullOrEmpty(value))
{
cookie = new HttpCookie("Foo", "Bar");
cookie.Expires = System.DateTime.UtcNow.AddHours(1);
this.Request.Cookies.Add(cookie);
}
}
protected void Application_EndRequest()
{
var cookie = this.Request.Cookies.Get("Foo");
string value = cookie?.Value;
}
}
What am I doing wrong? All of the posts I've seen relating to cookies shows setting/getting them in this fashion, with Request.Cookies.Get/Request.Cookies.Add.

You are not setting the cookie in this code you are only reading it, I made this same mistake. Use this
this.Response.Cookies.Add(cookie);
instead of
this.Request.Cookies.Add(cookie);
You should now see it in google chromes Application -> Cookies for your site

If you want to get state for each request, you have to do in Application_AcquireRequestState
Your Application_AcquireRequestState implementation should be :
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
var cookie = this.Request.Cookies.Get("Foo");
string value = cookie?.Value;
if (string.IsNullOrEmpty(value))
{
cookie = new HttpCookie("Foo", "Bar");
cookie.Expires = System.DateTime.UtcNow.AddHours(1);
this.Request.Cookies.Add(cookie);
}
}

Related

How to Encrypt and Decrypt cookie in an Existing Project without changing all pages code

I am working on a project with 1000s of pages in it which uses cookies. Now There comes an security issue , so I am planning to encrypt the cookie and decrypt when use it in page level.
Sample code i have used in Login page where my cookie gets created is as below:
Response.Cookies.Clear()
Response.Cookies("userinfo")("username") = "Pravin Kumar"
Response.Redirect("Home.aspx")
Now i wanna access that cookie in my HOME.aspx page . The code is as below.
Response.Write(Request.Cookies("userinfo")("username"))
This is how my project pages working till now and this enables user to view cookie in browser window like below :
Now My intention is i want to do some encrypting in LOGIN.aspx page and do the decryption in such a centralized place so that i no need to change all pages .
PS: I have tried with GLOBAL.asax page using
Sub Application_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
End Sub
But it didn't helped out.Pls suggest me if any simplest method found.
you will have to use HttpModule to override the behavior of the cookie read/write.
here is the sample code:
firstly, in your HttpModule
public class CookieEncryptModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PreSendRequestContent += Context_PreSendRequestContent;
context.BeginRequest += Context_BeginRequest;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
HttpApplication httpApplication = sender as HttpApplication;
for (int i = 0; i < httpApplication.Request.Cookies.Count; i++)
{
var cookie = httpApplication.Request.Cookies[i];
cookie.Value = dencryptCookieValue(cookie.Value);
}
}
private void Context_PreSendRequestContent(object sender, EventArgs e)
{
HttpApplication httpApplication = sender as HttpApplication;
for (int i = 0; i < httpApplication.Response.Cookies.Count; i++)
{
var cookie = httpApplication.Response.Cookies[i];
cookie.Value = encryptCookieValue(cookie.Value);
}
}
private string encryptCookieValue(string value)
{
return Convert.ToBase64String(Encoding.UTF8.GetBytes(value));
}
private string dencryptCookieValue(string value)
{
try
{
return Encoding.UTF8.GetString(Convert.FromBase64String(value));
}
catch
{
//in case some system generated cookies like session id will not be encrypted by our code
return value;
}
}
}
then in your web.config
<system.webServer>
<modules>
<add name="encryptCookie" type="[your_namespace].CookieEncryptModule, [your_assemably_name]"/>
</modules></system.webServer>
after above is done,
you cookies now will be stored in client with base64,
but to you server side codes it's transparent, you don't need to change anything
[notice]: this will make all JS fail to read the cookie value

asp.net tracking user info

How is the best way to track user information, sesssion Id, cookies? once for user session.
In Default.aspx:
protected void Page_Load(object sender, EventArgs e)
{
IF (!isPostPack)
{
var sessionValue= System.Web.HttpContext.Current.Request.Cookies["ASP.NET_SessionId"] != null ? System.Web.HttpContext.Current.Request.Cookies["ASP.NET_SessionId"].Value : string.Empty;
cONSOLE.WRITELINE(sessionValue);
}
}
This is not optimize. is there anyway to get only once the session iD,per user?
var sessionValue = System.Web.HttpContext.Current.Request.Cookies["ASP.NET_SessionId"]
!= null ?
System.Web.HttpContext.Current.Request.Cookies["ASP.NET_SessionId"].Value : string.Empty;
All that will give you is the identifier that ASP.Net uses to track the session. This is rarely something you need to directly access in code.
But assuming that is what you want, it will be extremely fast. To make it cleaner, you can:
Access Request directly (no need for HttpContext inside a Page)
Store the value in a class-level variable that will live for the lifecycle of the page.
private string _sessionId;
protected void Page_Load(object sender, EventArgs e)
{
_sessionId = Request.Cookies["ASP.NET_SessionId"] != null
Request.Cookies["ASP.NET_SessionId"].Value : string.Empty;
}
If you want to do this only once per session (per the comments):
protected void Session_Start( object sender, EventArgs e )
{
using( var writer = File.CreateText( #"c:\temp\session-id.txt" ) )
{
writer.WriteLine( Session.SessionID );
}
}

HTTP module re-writing the URL with some encryption

I am writing one class with the help of HTTPModule to check userIdentity in session before he access any page.If the variable in the session is null or empty i am redirecting the user in session expired page.
Code in Class:
public class SessionUserValidation : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication application)
{
application.PreRequestHandlerExecute += new
EventHandler(application_PreRequestHandlerExecute);
}
private void application_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
IHttpHandler handler = application.Context.Handler;
Page reqPage = handler as Page;
if (reqPage != null)
{
reqPage.PreInit += new EventHandler(CustomModule_Init);
}
}
private void CustomModule_Init(object sender, EventArgs e)
{
Page Page = sender as Page;
if (!Page.Request.Url.ToString().Contains("mySessionExpired.aspx") &&
!Page.Request.Url.ToString().Contains("myLogin.aspx"))
{
if (HttpContext.Current.Session["encryptedUserId"] == null)
{
HttpContext.Current.Response.Redirect("../Modulenames/mySessionExpired.aspx", false);
}
}
}
}
everything is working fine , only issue is that its adding some kind of encryption in URL for which my Breadcrumbs are not working in the page. The url transforms like :
://thewebsite/Project/(S(jnd4o5ljdgs0vq1zd4niby4a))/Pages/mySessionExpired.aspx
no idea why this fragment of text has been added ... please help
--Attu

How to dynamically initialize Culture in ASP.NET WebService Call?

Can anyone tell me how can i dynamically initialize thread culture in a asp.net webservice call?
In my aspx pages i have a base page where i override the InitializeCulture() Method.
Note that the value of selected language is saved in Session State.
In Global.asax file you can set the current culture, even if its web service or web page.
// PreRequestHandlerExecute occurs after initialization of Session
void Application_PreRequestHandlerExecute(Object Sender, EventArgs e)
{
// check if session is required for the request
// as .css don't require session and accessing session will throw exception
if (Context.Handler is IRequiresSessionState
|| Context.Handler is IReadOnlySessionState)
{
string culture = "en-US";
if (Session["MyCurrentCulutre"] != null)
{
culture = Session["MyCurrentCulutre"] as String;
}
System.Threading.Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.CreateSpecificCulture(culture);
}
}
You are changing your requirements, however Session object will not be available in Begin_Request method, you can do this in your web method.
[WebMethod]
public static string MyWebMethod()
{
String culture = Session["MyCurrentCulutre"] as String;
System.Threading.Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.CreateSpecificCulture(culture);
return "My results";
}

Set culture using cookie in asp.net, not updated

I'm using asp.net and want to make it possible for the user to set the culture to use in the website by himself. In MasterPage I have the following code to set a language cookie:
protected void Page_Load(object sender, EventArgs e) {
if (Request.QueryString["setLanguage"] != null)
{
HttpCookie languageCookie = new HttpCookie("language");
languageCookie.Value = Request.QueryString["setLanguage"];
languageCookie.Expires = DateTime.Now.AddDays(10);
Response.SetCookie(languageCookie);
}
}
In Global.asax I use the cookie like this:
protected void Application_BeginRequest(object sender, EventArgs e) {
HttpCookie languageCookie = System.Web.HttpContext.Current.Request.Cookies["language"];
if (languageCookie.Value != null)
{
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(language);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
}
}
The problem is that after I set the cookie with Response.SetCookie I need to reload the page to get the new language. How can I make my code so when the user set a new language the page is reloaded with the new language directly?
You can do
Response.Redirect(Request.PathAndQuery);
But why not just set the language after setting the Cookie? You can even use the BeginRequest event to check for specific input being posted and use it as an alternative condition for setting the language.
I had the same issue with the language being selected by the user. In order for it to work you have to do it on
protected override void InitializeCulture()
{
HttpCookie languageCookie = System.Web.HttpContext.Current.Request.Cookies["language"];
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(language);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
}
In order for it to work on every page of the site, I created a class that inherited from System.Web.UI.Page and implemented there
public class myBasePage : System.Web.UI.Page
{
protected override void InitializeCulture()
{
HttpCookie languageCookie = System.Web.HttpContext.Current.Request.Cookies["language"];
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(language);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
base.InitializeCulture();
}
}
from then on I had all my pages inherit from myBasePage.
This way, I used a Server (Postback) control to set the language and the page would get reloaded, and the language would be set.
If you are using Asp.Net MVC
//A foreigner, has possibly brew a cookie for me
public class SpeakNativeTongueAttribute : ActionFilterAttribute, IActionFilter
{
const string cookieName = "culture";
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
var cookieKeys = filterContext.RequestContext.HttpContext.Request.Cookies.AllKeys;
if (cookieKeys.Contains(cookieName))
{
//eat the cookie
var theCultureCookie = filterContext.RequestContext.HttpContext.Request.Cookies[cookieName];
var theCulture = theCultureCookie.Value;
//say thanks in native tongue
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo(theCulture);
System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(theCulture);
}
else
{
//Didn't receive a cookie, don't speak their language, those bastards!
}
}
}

Resources