session.abandon is not generating new session - asp.net

I am using asp.net 3.5
Session.Abandon() is not using the new SessionId.
Session["abc"] = "abc";
Session.Abandon(); //Session id is same as checked in add watch

Yes, and this is by design. It will reuse the same session ID.
See http://support.microsoft.com/kb/899918
Also
http://weblogs.asp.net/karan/archive/2010/04/26/asp-net-session-state-revisited.aspx

You can Session.IsNewSession to identify wether the sesiion is new one or not instead of using the SessionId, ASP.net reuses SessionId, as suggested in the KB Article you can get around this by programmatic-ally setting the SessionId to null in the client side cookies.
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
Response.Redirect(Request.Path);

Session.Clear() then the session variables clear up but the user remaining in the same session (if you don't want him to relogin for example) and reset all his session specific data.
Session.Abandon() only takes effect after page is completely executed. So the current page that called Abandon still has that same session. All next browser calls will be on a new Session.i.e You lose that specific session and the user will get a new session key.

Related

Setting a Cookie on Session Start in ASP.Net if QueryString Variable Present

I am looking to more accurately track a marketing plan that is sending traffic to my asp.net website. Currently, I have coded into individually pages to look for the referral querystring parameter "gclid".
Example: http://example.com/landingpage.aspx?gclid=[vlue]
I was hoping there was a way to make this process global for any landing page in my site and set a cookie equal to the value of gclid only when it is found in the querystring of a landing page.
Is this something that done reliably with Session_OnStart?
The Session_Start event in the Global.asax file is one alternative that you can use for this. See answer by #sh1rts.
But the Session_Start event (of course) only fires when a new session is started. Hypothetical situation:
A user clicks a link on some other site and arrives on your site
Session_Start runs and stores the gclid value to the new session
User goes back to the other site
A short while later the user clicks another link and once again comes to your site
User already has a session on your site, so Session_Start is not triggered again
If the gclid is different the second time, the session won't be updated with that value. This may not be a problem in practise, so Session_Start may be a solution. If this could be a problem, then you can use a different event in Global.asax that runs for every request. For example Application_PostAcquireRequestState:
void Application_PostAcquireRequestState(object sender, EventArgs e)
{
var httpApp = sender as HttpApplication;
if(httpApp != null && httpApp.Context != null && httpApp.Context.Session != null)
{
if(!string.IsNullOrEmpty(httpApp.Context.Request.QueryString["gclid"]))
httpApp.Context.Session["gclid"] = httpApp.Context.Request.QueryString["gclid"];
}
}
Yes, Session_Start is a reliable way to do this.
At this point HttpContext.Current will be valid, so you can get to the querystring using HttpContext.Current.Request.QueryString, i.e.
var gclid = HttpContext.Current.Request.QueryString["gclid"];

ASP.NET session key for web service security?

I've got a web service (ASP.NET 2.0) that I'm calling from javascript using jQuery's $.ajax(). I've been told that the session key is often used as a nonce in a situation like this for security purposes; the web service takes a key as one of its parameters and only returns data if it matches the current session key.
I'm attempting to accomplish this by setting the value of a hidden field to the current SessionID on every Page_Load (i.e. every postback), then grabbing it in the javascript to pass as a parameter. But it's never the same key as the web service's current key (Context.Session.SessionID).
Is this possible to resolve, or should I be doing this another way?
EDIT: code to set session in hidden field as requested.
hfSession.Value = Context.Session.SessionID;
That's in the Page_Load of a .ascx control, not under any conditional (i.e. not wrapped with if (!Page.IsPostBack).
I believe you are trying to prevent Cross Site Script Request Forgery (CSRF). The Session ID is actually sent across as a cookie and the attacker can set this. Rather than use the Session ID itself, you should use a randomly generated number stored in a Session variable.
String GetCSRFToken()
{
String token = (String)Session["CSRFToken"];
if( token == null )
{
token = GenerateLongRandomString();
Session["CSRFToken"] = token;
}
return token;
}
void AssertValidCSRFToken(String token)
{
if( token != GetCSRFToken() )
{
throw new Exception("Invalid Request!")
}
}
Here is a link to another question with more info on preventing this kind of attack:
CSRF Validation Token: session id safe?
Asp.net actually generates a new Session ID for every request until you use the Session State to store some value. This could be a reason why the values are different. Try and save something in the session. Perhaps
Session["SessionID"] = Context.Session.SessionID;
hfSession.Value = Context.Session.SessionID;
A new SessionID is generated each time the page loads until the session is actually allocated. So if you don't actually allocate anything to the session, the SessionID will change upon each page load.

How to implement login session in asp.net and C#

I'm new to asp.net and C# and I want to ask how to implement a session login using asp.net and C#.
Please advise.
Thanks.
In C# you can define a session variable like this:
Session["userame"]= txtusername.Text;
where txtusername is a text box. In another page you can call it as:
string usrname = Session["username"].ToString();
To check whether a user is logged in or not, in a particular page; you'll have to check if this session is empty or not. If the session is null then redirect the user to login page else he/she can view the page. Same logic applies to all the pages where you want to implement the session validation. Sample (on Page_Load event):
if (Session["username"] == null)
Response.Redirect ("Login.aspx");
Hope it helps... :)
The question is broad answer, in Simply you can follow like this
Create database, user table in sql server or any database of your choice
Create the login form with userid and password
Check them with database for user availability
If User exist and password matches create a session, like Session.Add ("Userid", txtUserid.Text);
In other pages (restricted pages where only registered users allowed) write this code in every page load event
if (Session["Userid"] == null)
Response.Redirect ("Login.aspx");
Session["login_user"] = "[username]";
string username = Session["login_user"].ToString().Trim();
Easiest way to implement session is as following:
Session["SessionName"] = Value;
For retrieving value
String variable = Session["SessionName"].ToString();
Note: Session variable can be of any type.
Generally session is used for checking whether the user is logged in or not.

Where should i store "MemberID"?

In my webpage i use FormsAuthentication
FormsAuthentication.RedirectFromLoginPage(VisitorEmail, False)
Every time the visitor gets authenticated via the login page, i set the
Session("MemberID") = GetMemberIDByEmail(VisitorEmail) for later processing.
Since i need both MemberID and VisitorEmail.
But something tells me that this is "out of the book" and not "by the book".
So am i doing something WRONG or BAD here?
Sorry, I'm not sure exactly what you are trying to do from your description, but there's no need to store the MemberID in session state. Whenever you need it, just call:
Membership.GetUser.ProviderUserKey
Note: Its not really considered good form to store information in Session state as this could be lost e.g. if the web server resets - which it does periodically, or if the site needs to recompile. Also, its not very scalable as each "active" user will use up memory and also if you ever need to move to a web farm session state can cause issues as it will be different on each web server.
Prob OK for a little, quick site though ;-)
It's fine to use Session to cache this type of info, but remember to reassign it when the session expires in Global.asax:
void Session_Start(object sender, EventArgs e)
{
if(Request.IsAuthenticated) //to make sure the user has not logged out
Session["MemberID"] = GetMemberIDByEmail(VisitorEmail);
}
You could create a custom principal class so you can add the additional properties. Then modify your Global.asax to override Application_PostAuthenticateRequest with your code and also set Context.User = Thread.CurrentPrincipal = myPrincipal;. Best is to always set Thread.CurrentPrincipal, but normally you can also get to your own properties elsewhere in your code using the more "convenient" Page.User or Context.User.
Context.User vs. Thread.CurrentPrincipal / why FormsAuthentication can be subtle
Set custom IIdentity or IPrincipal / Store user id in Principal or Identity?
Could you not switch the two around and store the member id in the form variable (since I assume the user is able to change there email address and not there member id)...
Dim memberId as Integer = GetMemberIDByEmail(VisitorEmail)
' assuming integer here and that a result is found etc etc
' set the form authentication stuff
FormsAuthentication.RedirectFromLoginPage(memberId, False)
And then you can always look up the email address from the memberId (caching it perhaps against the member id across requests)
Public Function GetMemberEmail(Byval memberId as Integer) As String
Dim cacheKey as String = "member-email-" & memberId
Dim email as String
If Cache.Item(cacheKey) is Nothing Then
email = GetMemberEmailByID(memberId)
Cache.Insert(cacheKey, email ...
Else
email = Cache.Item(cacheKey)
End If
return email
End Function
If you need both pieces of information, and the Id is less likely to change, it would seem the better value to be used for your forms authentication....and you can always look up the email address from the value.

.net cookies, do I have to send to browser?

After I create or modify a httpcookie, do I have to do add it to the response.cookies collection? (if yes, only if its a new cookie or even if I am modifying one)
If you don't add a cookie to the Response.Cookies collection, it will never be sent to the browser. However, once you add the cookie to the collection, you can modify it as you please and the last value you set is what will be sent to the browser. What you are adding to the collection is a reference to your HttpCookie object, and the cookie is not sent to the browser until the end of the request life cycle.
If it is new it needs to be added to the Response.Cookies collection to be stored, but you can access the collection like an array.
Response.Cookies["foo"] = myCookie;
This will take care of the adding for you. FYI, if the cookies has not been created the value will return null.
However the cookie will be updated if you refer to the collection like this:
HttpCookie myCookie = Response.Cookies["foo"];
Any modifications to myCookie will be made to the cookie in the collection because in C# when you assign a variable to an existing class object, that object is handled by reference and it is modified.

Resources