ASP.NET Session in Global.asax - asp.net

Session in Application_AuthenticateRequest method in Global.asax is always null.Ive already try:
this.Session,HttpContext.Current.Session
always null.
protected void Application_AuthenticateRequest()
{
string userRole = string.Empty;
if (Request.IsAuthenticated)
{
if (this.Session["UserRole"] == null)
{
InsertSessionValue();
}
userRole =Session["UserRole"].ToString();
HttpContext.Current.User = new GenericPrincipal(User.Identity, new string[] {userRole});
}
}
Ive also try to use Cache,but it doesnt work because i need unique information for each user.
How to use Session in Global.asax?Is HttpApplication Application property unique for each user?

You just can't use Session at this point in the request lifecycle, it isn't available/populated yet, if you want to use it you'll need to move to an event later in the lifecycle, for example PostAcquireRequestState.

Related

Where to create custom IPrincipal object?

I am using Application_PostAuthenticateRequest event in global.asax to create custom IPrincipal object
void Application_PostAuthenticateRequest(object sender, EventArgs args)
{
if (Context.User.Identity.IsAuthenticated == true)
if (Context.User.Identity.AuthenticationType == "Forms")
{
Context.User = new CustomPrincipal(Context.User);
Thread.CurrentPrincipal = Context.User;
}
}
to use in my application where I want get some more information about logged user. I thought it would be called one time when user authenticates but I noticed that it is called on every page request couple times for the same logged user. I found that even requesting image from AppThemes calls this method!
Where should I create that object instead to avoid calling this method multiple times for each user?
I found an answer to my question.
In loggin_in event I should save authentication cookie (I can store all information that I later need in my customPrincipal in UserData property) and in Application_PostAuthenticateRequest I should create CustomPrincipal from that cookie.
That way this event fires every request but I don't hit database - I read data from cookie.
I followed http://www.ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html
In my case code is:
void Application_PostAuthenticateRequest(object sender, EventArgs args)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null)
return;
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
string[] customData = authTicket.UserData.Split(new Char[] { '|' });
if (Context.User.Identity.IsAuthenticated == true)
{
if (Context.User.Identity.AuthenticationType == "Forms")
{
Context.User = new CustomPrincipal(customData, Context.User);
Thread.CurrentPrincipal = Context.User;
}
}
}
Context.User does not save the new principal across requests; you have to create the custom principal on every request. So it may be best to leave this code here. Otherwise, it will revert to FormsPrincipal or WindowsPrincipal, depending on application authentication mode.
HTH,
Brian

Session expiration issue in ASP.NET MVC

Hi I have some issues with ASP.NET MVC session state which is not expiring after I implement the following piece of code and put the attributes over the methods.
public sealed class SessionActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
//Check if session is supported
if (ctx.Session != null)
{
//Check if the session is new
if (ctx.Session.IsNewSession)
{
//If it says it is a new session but an existing cookie exists
//then it must have timed out
string sessionCookie = filterContext.HttpContext.Request.Headers["Cookie"];
if ((sessionCookie != null) && (sessionCookie.IndexOf("ASP.NET_SessionId", StringComparison.OrdinalIgnoreCase) >= 0))
{
//Redirect to the login page
ctx.Response.Redirect("~/Home/Index", true);
ctx.Response.End();
}
}
}
base.OnActionExecuting(filterContext);
}
}
The issue is that the Redirection request is not executing and the Action which has SessionActionFilter Attribute executes. This method uses session variables which are expired and results in error.
Can anybody tell what I am missing?
Thanks a lot in advance!!
We are storing some data which is used in our views!! One more update I was able to run this piece of code which is now working fine. However, I am a bit skeptical about the use of cookies and need to transform this code to work for cookieless sessions also. How is this possible?

Is there any way to get the requesting user's ID in an ASP.NET web service method?

I know this probably isn't possible, but I would like to be able to get the Request user ID from within an ASP.NET web service method. So far, I've tried User.Identity.Name, Context.Request.LogonUserIdentity.Name, Request.ServerVariables["AUTH_USER"] and Request.ServerVariables["LOGON_USER"]. Am I tilting at windmills here, or is there something super simple that I'm missing?
Well, what do you mean by User ID?
If they've authenticated via Windows Authentication, User.Identity gives you the WindowsIdentity object that corresponds to that user.
If you want the User ID which corresponds to an authenticated user to "magically" show up in your pages, you can do that too! In your Global.asax, there is a function called Application_AuthenticateRequest which you implement to take whatever identity is passed to your application and turn it into a IPrincipal-based object which can be accessed from your pages.
So when you implement AuthenticateRequest(), you can take the HttpContext.Current.User.Identity.Name, and use that to look up your User ID from your database. From there, you construct your own IPrincipal-derived object and set the HttpContext.Currrent.User reference to that object you create. You can then cast "User" in your pages over to the object you create and read the User ID. We do this all the time. Here's some sample code (which actually caches the Principal object so that you don't have to go to the DB on every request):
protected void Application_AuthenticateRequest(object sender, EventArgs e) {
try {
IIdentity myIdentity = HttpContext.Current.User.Identity;
MyPrincipal myPrincipal = (MyPrincipal)HttpContext.Current.Cache[myIdentity.Name];
if (myPrincipal == null) {
myPrincipal = (MyPrincipal)GetPrincipalFromDatabase(HttpContext.Current.User.Identity);
HttpContext.Current.Cache.Insert(myIdentity.Name, myPrincipal, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero);
}
HttpContext.Current.User = myPrincipal;
}
catch (SecurityException) {
HttpContext.Current.User = null;
}
catch (Exception ex) {
Trace.WriteLine("Could not validate your user.");
}
}

ASP.NET - Get SessionID while in from the Global.ASAX

I'm recording the session start times from when people log into my .NET 2.0 web application, but I'd also like to record the Session ID. Can someone give me some example code on how to accomplish this (how to access the Session ID from within the Global.ASAX).
If you need any additional info just let me know.
HttpContext.Current.Session.SessionID
Edit to show null test:
if ((HttpContext.Current != null) && (HttpContext.Current.Session != null) {
id = HttpContext.Current.Session.SessionID
}
You can get at it quite simply with HttpContext.Current.Session.SessionId as you probably already know. You need to be on or after Application_AcquireRequestState before the session state has been loaded, and session state is also only loaded when the requested resource implements IRequiresSessionState. You can see a list of all the events in global.asax here: https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5771721.html and read more about IRequiresSessionState here: http://msdn.microsoft.com/en-us/library/system.web.sessionstate.irequiressessionstate.aspx
Write to the session the datetime and sessionid at the moment of the first request following ASP.NET's identifying the user's session.
protected void Application_PreRequestHandlerExecute(object sender, EventArgs eventArgs) {
var session = HttpContext.Current.Session;
if (session != null) {
if (session["foo"] == null) {
session["foo"] = DateTime.Now.Ticks + "|" + session.SessionID;
}
}
}

ASP.NET 2.0: Problem in Httpcontext.current.session.add()

Can anybody help me to find out solution of following problem.
In ASP.NET website: at Application_OnPostAuthenticate() event, whatever code i write is executed for every request. therefore due to this customidentity object, countryid and weatherid is called everytime for each request (call for database for value). It effect response time of page and unneccessary code execute.
void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
// Get a reference to the current User
IPrincipal objIPrincipal = HttpContext.Current.User;
// If we are dealing with an authenticated forms authentication request
if ((objIPrincipal.Identity.IsAuthenticated) && (objIPrincipal.Identity.AuthenticationType == "Forms"))
{
CustomPrincipal objCustomPrincipal = new CustomPrincipal();
objCustomPrincipal = objCustomPrincipal.GetCustomPrincipalObject(objIPrincipal.Identity.Name);
HttpContext.Current.User = objCustomPrincipal;
CustomIdentity ci = (CustomIdentity)objCustomPrincipal.Identity;
HttpContext.Current.Cache["CountryID"] = FatchMasterInfo.GetCountryID(ci.CultureId);
HttpContext.Current.Cache["WeatherLocationID"] = FatchMasterInfo.GetWeatherLocationId(ci.UserId);
Thread.CurrentPrincipal = objCustomPrincipal;
}
}
To solve this problem when i try tochange code as follows
HttpContext.Current.Session.Add("test", FatchMasterInfo.GetWeatherLocationId(ci.UserId);); in place of cache i found foolowing error
"Object refrence not set to the instance of object"
I don't know whether we can store session variable inside Application_OnPostAuthenticate() event or not?
You could try doing this a bit later in the request, such as in the PreRequestHandlerExecute event:
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
IPrincipal objIPrincipal = HttpContext.Current.User;
if ((objIPrincipal.Identity.IsAuthenticated) && (objIPrincipal.Identity.AuthenticationType == "Forms"))
{
HttpSessionState session = HttpContext.Current.Session;
CustomPrincipal objCustomPrincipal = new CustomPrincipal();
if (session[objIPrincipal.Identity.Name] == null)
{
// get data from database or wherever
objCustomPrincipal = objCustomPrincipal.GetCustomPrincipalObject(objIPrincipal.Identity.Name);
CustomIdentity ci = (CustomIdentity)objCustomPrincipal.Identity;
Object countryID = FatchMasterInfo.GetCountryID(ci.CultureId);
Object weatherLocationID = FatchMasterInfo.GetWeatherLocationId(ci.UserId);
// save in session (not cache as cache is application-wide, not per-user):
session.Add(objIPrincipal.Identity.Name, objCustomPrincipal);
session.Add(objIPrincipal.Identity.Name + "_CountryID", countryID);
session.Add(objIPrincipal.Identity.Name + "_WeatherLocationID", weatherLocationID);
}
else
{
// already have custom principal object in session
objCustomPrincipal = (CustomPrincipal)session[objIPrincipal.Identity.Name];
}
// set the custom principal object to context/thread
HttpContext.Current.User = objCustomPrincipal;
Thread.CurrentPrincipal = objCustomPrincipal;
}
}
You probably don't want to access the session in any event that happens in every request. Some requests don't even have session (for instance, a lot of web service calls, or calls to WebResource.axd that load static resources).
Before adding value to cache object, check if it already exists in the cache.
You might not have session state enabled. Does it work anywhere else (like in a web form's display)?
Look for a <sessionState> element under your system.web element in web.config make sure it's turned on (set it to InProc unless you have a web farm).

Resources