asp.net ajax calls to user controls - asp.net

When calling page methods or web services with either jquery or MSAjax, the Session object appears to be null so Im finding it hard to track users who execute them.
Seeing that the session id is sent with the cookie on each request, is it possible to obtain the session object from somewhere?

You can enable the session in your WebMethod attribute like so.
[WebMethod(EnableSession = true)]
This should enable you to access the Session object.

Related

How to get session value in code file while session is created in httphandler

How to get session value in code file while session is created in httphandler .it gives error like Object reference not set to an instance of an object.
The session is connected with a page request, to work is require to read the cookie of the user from the browser, or the url in case that is with out cookies.
So in the asp.net session if you do not have the httphandler, you can not have the session, because you can not know who is calling and see the page at that time.
Maybe in a custom solution session, you can send the session id to some other code with out the httphandler and use that id to read the session data, but the asp.net did not give this option.

how to change session id after login in asp.net

I have a website that's using forms authentication and membership. A user must have cookies enabled to use the site. I've been asked to change the code so that the session id is changed as soon as a user logs in. Aparently this will protect against a Session Fixation attack (http://en.wikipedia.org/wiki/Session_fixation). Does anyone know how I can change the session id without losing the whole session ? PHP has a specific method for doing this but I can't find a .NET equivalent.
Here's a blog post that talks about this:
ASP.NET does not directly support
functionality to regenerate a session
ID. See the documentation regarding
the issue here. There is a not-so
quick and dirty way to do it by
setting the ASPNET_SessionID value to
the empty string and redirecting so
that the value is regenerated.
I have answered a similar question at Generating a new ASP.NET session in the current HTTPContext. Basically we must change some of the SessionStateModule internal state to be able to regenerate session ID without losing objects in the Session. I used reflection to set the _rqId field to the new ID and _rqSessionStateNotFound to true. The downside is we must grant "Full Trust" to the Application.
This is a really old question I'm resurrecting, but here's the solution:
var manager = new SessionIDManager();
bool redirected, isAdded;
manager.SaveSessionID(System.Web.HttpContext.Current,
"5vonjb4mtb1of2fxvhjvkh5d", out redirected, out isAdded);
// sessionId now equals "5vonjb4mtb1of2fxvhjvkh5d"
var sessionId = Session.SessionID;
The method suggested in Microsoft's obsolete KB article 899918 works well even for .NET framework 4.5 Web Forms applications. Here is the archive of the article: https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/899918
How and why session IDs are reused in ASP.NET
Article ID: 899918
Article Last Modified on 9/8/2006
APPLIES TO
Microsoft .NET Framework 1.1
INTRODUCTION
This article describes how and why Microsoft ASP.NET session IDs are used.
MORE INFORMATION
The ASP.NET session state is a technology that lets you store server-side, user-specific data. Web applications can use this data to process requests from the user for which the session state was instantiated. A session state user is identified by a session ID. The session ID is delivered by using one of the following methods:
The session ID is part of a cookie that is sent to the browser of the user.
The session ID is embedded in the URL. This technique is also known as a cookie-less session.
Session IDs are a 120-bit random number that is represented by a 20-character string. The string is formatted so that it can be included in a URL and it does not have to undergo URL encoding. For example, the string may be used in cookie-less sessions. The most commonly used method of delivering session IDs is by using cookies to store the session IDs.
When a user first opens their Web browser and then goes to a Web site that implements ASP.NET session state, a cookie is sent to the browser with the name "ASP.NET_SessionId" and a 20-character value.
When the user browses within the same DNS domain, the Web browser continues to send this cookie to the domain for which it was sourced.
For example, app1.tailspintoys.com and app2.tailspintoys.com are both ASP.NET applications. If the user goes to app1.tailspintoys.com and then goes to app2.tailspintoys.com, both applications would use the same cookie and the same session ID to track the session state of the user within each application. The applications do not share the same session state. The applications only share the session ID.
Therefore, you can reuse session IDs for several reasons. For example, if you reuse session IDs, you do not have to do the following:
Create a new cryptographically unique session ID when you are presented with a valid session ID.
Create a new session ID for every ASP.NET application that is in a single domain.
When the Web application requires a logon and offers a log off page or option, we recommend that you clear the session state when the user has logged off the Web site. To clear the session state, call the Session.Abandon method. The Session.Abandon method lets you flush the session state without waiting for the session state time-out. By default, this time-out is a 20-minute sliding expiration. This expiration is refreshed every time that the user makes a request to the Web site and presents the session ID cookie. The Abandon method sets a flag in the session state object that indicates that the session state should be abandoned. The flag is examined and then acted upon at the end of the page request. Therefore, the user can use session objects within the page after you call the Abandon method. As soon as the page processing is completed, the session is removed.
When you use the in-process session state mode, these session state objects are stored in the HttpCache. The HttpCache supports a callback method when the following conditions are true:
A cache entry is removed.
The Session State Manager registers the Session_OnEnd event handler to be called when the cache entry is removed.
When the Session State Manager removes a session state object that resides in the cache, the HttpCache manager will call any registered callbacks. In effect, this behavior raises the Session_OnEnd event handler.
When you abandon a session, the session ID cookie is not removed from the browser of the user. Therefore, as soon as the session has been abandoned, any new requests to the same application will use the same session ID but will have a new session state instance. At the same time, if the user opens another application within the same DNS domain, the user will not lose their session state after the Abandon method is called from one application.
Sometimes, you may not want to reuse the session ID. If you do and if you understand the ramifications of not reusing the session ID, use the following code example to abandon a session and to clear the session ID cookie:
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
This code example clears the session state from the server and sets the session state cookie to null. The null value effectively clears the cookie from the browser.
When a user does not log off from the application and the session state time-out occurs, the application may still use the same session state cookie if the browser is not closed. This behavior causes the user to be directed to the logon page and the session state cookie of the user to be presented. To guarantee that a new session ID is used when you open the logon page (login.aspx), send a null cookie back to the client. To do this, add a cookie to the response collection. Then, send the response collection back to the client. The easiest way to send a null cookie is by using the Response.Redirect method. Because the cookies collection always has a value for the ASP.NET_SessionId, you cannot just test if this cookie exists because you will create a Response.Redirect loop. You can set a query string on the redirect to the logon page.
Or, as illustrated in the following code example, you can use a different cookie to tell if you are already redirected to the logon page. To help enhance security and to make sure that no one tries to open the logon page by using a second cookie together with the ASP.NET cookie, the following code example uses the FormsAuthentication class to encrypt and decrypt the cookie data. Then, the code example sets a 5-second time-out.
private void Page_Load(object sender, System.EventArgs e)
{
if( !IsPostBack && ( Request.Cookies["__LOGINCOOKIE__"] == null || Request.Cookies["__LOGINCOOKIE__"].Value == "" ) )
{
//At this point, we do not know if the session ID that we have is a new
//session ID or if the session ID was passed by the client.
//Update the session ID.
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
//To make sure that the client clears the session ID cookie, respond to the client to tell
//it that we have responded. To do this, set another cookie.
AddRedirCookie();
Response.Redirect( Request.Path );
}
//Make sure that someone is not trying to spoof.
try
{
FormsAuthenticationTicket ticket =
FormsAuthentication.Decrypt( Request.Cookies["__LOGINCOOKIE__"].Value );
if( ticket == null || ticket.Expired == true )
throw new Exception();
RemoveRedirCookie();
}
catch
{
//If someone is trying to spoof, do it again.
AddRedirCookie();
Response.Redirect( Request.Path );
}
Response.Write("Session.SessionID="+Session.SessionID+"<br/>");
Response.Write("Cookie ASP.NET_SessionId="+Request.Cookies["ASP.NET_SessionId"].Value+"<br/>");
}
private void RemoveRedirCookie()
{
Response.Cookies.Add(new HttpCookie("__LOGINCOOKIE__", ""));
}
private void AddRedirCookie()
{
FormsAuthenticationTicket ticket =
new FormsAuthenticationTicket(1,"Test",DateTime.Now,DateTime.Now.AddSeconds(5), false,"");
string encryptedText = FormsAuthentication.Encrypt( ticket );
Response.Cookies.Add( new HttpCookie( "__LOGINCOOKIE__", encryptedText ) );
}

ASP.NET Access current session using jQuery

Is there a way to modify the current Session() variable using jQuery? If it involves deconstructing the ViewState then I'm not really interested. Just curious if there was some easy way to do it.
Thanks!
If you need to pass a per session property between jQuery and the server you could try using cookies instead.
Otherwise you'll have to create a custom handler (ashx) file or a WebMethod or similar that lets you access it with Ajax calls.
jQuery
$.get("http://somewhere/page.aspx",
{sessionVar: "something"},
function(data)
{
alert("Session(\"something\") = " + data);
}
);
page.aspx:
Response.Write(Session[Request.QueryString["sessionVar"]]);
That's with no error checking or anything...
Session is stored on the server and you can't access it from jQuery unless you make an ajax call and get the session details from server.
Other than the fact that both ViewState and Session helps developer maintain state in their web application, they have nothing to do with each other.
EDIT:
If you want to modify the session using Ajax. Create an HTTP handler SessionHelper.ashx. This session handler can take 'SessionVariableName' and 'SessionVariableValue' as Query String parameters and modify the session state on the server. You can call this handler from jQuery using $.ajax method.
Please keep in mind that if you expose an handler like that, you will have to protect it against misuse as any person can call the handler directly and modify the Session variables. [e.g. If you store User role/privileges in session, a hacker can modify this role/privileges through this handler.]

ASP.NET global events

which event is the most suitable to check for Session expired? i'm trying to trap each server request, and if Session is null, redirect to a different page.
You can determine if a new session is being created by hooking Session_OnStart - http://msdn.microsoft.com/en-us/library/ms178583(VS.80).aspx
You can handle the Session_OnStart
event by adding a subroutine named
Session_OnStart to the Global.asax
file. The Session_OnStart subroutine
is run at the beginning of a request
if the request begins a new session. A
new session will be started if a
request is made that does not contain
a SessionID value or if the SessionID
property contained in the request
references a session that has expired.
This will tell you effectively when a new session is being created, regardless of if the user just arrived or the session had expired.
It would be hard to reliably differentiate between both scenarios. I guess you could try to get a hold a the session id in the either the session cookie or embedded in the url (cookieless), but you would need to check it before getting to the above event, and later check whether the request had a session id originally. Check if you can get to the session id in the cookieless version, because it is stripped out of the urls asp.net gives you (not sure if early in the lifecycle you get to see it).
This is often best achieved by using a base Page class for all otehr classes, and implementing this in the Page_Load method.
Use BasePage class, which inherits from Page class. Let every aspx page inherits that BasePage class. In BasePage class, override OnInit event, in which you can check for Session or Cookie, and redirect user to login page (for example).
I use this approach for all mine webforms apps, because it's easy to implement and use.

Can I abandon an InProc ASP.NET session from a session different than one making the request?

We have an application that does single sign-on using a centralized authentication server (CAS). We'd like to do single sign-out, such that if the user logs out of one application (say a front-end portal), the user is automatically signed out of all applications using the same single sign-on ticket.
The expectation would be that each application would register a sign-out hook (URL) with the CAS at the time of logon to that application. When the CAS receives the sign out request from one of the applications, it invokes the sign-out hook for all the application sharing the SSO ticket.
My question is this: is there a way to abandon an InProc session from a different session? I presume, since the HTTP request will be coming from the CAS server, that it will get its own session, but it is the session of the user that I want to terminate. I have pretty good idea of how to do this using a separate session state server, but I'd like to know if it is possible using InProc session state.
Haha, well... It looks like you can. I was wondering myself if there was any way to do this, turns out, there is.
When you use InProc, the InProcSessionStateStore (internal class) persist the session state in an internal (non public) cache. You can access this cache through reflection and remove the session state manually.
using System;
using System.Reflection;
using System.Web;
object obj = typeof(HttpRuntime).GetProperty("CacheInternal",
BindingFlags.NonPublic | BindingFlags.Static)
.GetValue(null, null);
if (obj != null)
{
MethodInfo remove = obj.GetType()
.GetMethod("Remove", BindingFlags.NonPublic | BindingFlags.Instance,
Type.DefaultBinder, new Type[] { typeof(string) }, null);
object proc = remove.Invoke(obj, new object[] { "j" + state.SessionID });
}
The end result is, that the next request will take on the same SessionID, but the HttpSessionState will be empty. You'll still get the Session_Start and Session_End events.
After doing a bit of digging around and considering the answers provided so far I've come up with an alternative that lets me continue to use InProc session. Basically, it consists of extending the HttpModule that already handles single sign-on to detected CAS sign outs and redirect the browser to the application sign out page.
Outline:
Sign-On:
For each new single sign-on request, create a new SSO cookie and encode a unique value in it to identify the session (not the session id, so it isn't leaked).
Construct the the sign-out callback url, encoded with the identifier, and register it with the CAS server.
Sign-Out:
When a sign-out request is received from the CAS server, decode the identifier and store it in an application-wide cache. This needs to be pinned in the cache at least long enough for the session to expire naturally.
For each request, look for the SSO cookie and check its value against the cached, signed-out session identifiers. If there is a hit, remove the SSO cookie and redirect the browser to the application's sign-out url.
For each sign-out, check to see if there is an SSO cookie, if so, forward the sign-out request to the CAS. In any event, abandon the user's session, and sign them out of the application.
Page_Load:
Check for the presence of the SSO cookie. If there isn't one, redirect to the sign out page.
No can do.
http://forums.asp.net/p/416094/416094.aspx#416094
With InProc SessionState, you won't be able to access the data... With StateServer, you still will have a sticky scenario trying to access the correct API to remove the session.
You will most likely want to use a database backed state solution like the pre-packaged SqlServer state provider or a third party solution like DOTSS: http://codeplex.com/dotss
With the database backed solution, you will be able to lookup the state record in a table by session id and mark it as completed. These techniques will vary based on the provider you choose.

Resources