What sets Page.User.Identity.Name - asp.net

I keep track of the current logged in userID and base the behavior of my site on this value. My code sets the logged in user ID with this statement:
FormsAuthentication.SetAuthCookie(UserID.ToString(), true);
Subsequently, I read this value from Page.User.Identity.Name.
This works fine on my desktop, but on my server, I set it to 8 and it comes back 20. I am trying to figure out what can set Page.User.Identity.Name to a value and when this happens.
Thanks...

FormsAuthenticationModule handles Application_OnAuthenticate and assigns the HttpContext.User to a prinicipal object which is in turn used by Page.User.Identity.Name.
Isn't there a time difference issue on the server and your desktop?

Related

Access data in asp.net attribute

Our webapp-solution needs a login preventer that gives the user a 10 seconds penalty (in where he cannot log in) after three incorrect logins.
Today this task is solved by an attribute, ToggleAttribute (custom), that contains a counter keeping track of the users number of logins attempts.
If the number exeeds the defined limit (default 3) the ToggleAttribute will redirect the user back to the login page with a 10 sec penalty.
This works OK. However, the problem occurs when the user has successfully logged in and out. The counter is not reset, so the next user gets only two login attempts.
I would like a way to reset the counter inside the attribute from our login controller if password validation is good. May I access the data in the Attribute from the controller?
The problem was solved by putting the counter data into a cache that is aslo accessable outside of the attribute. By doing so, the login controller may reset counter. It is not a perfect solution, but works until we implement a authorization solution further up the road.

I only seem to be able to set one Cookie - HttpCookie, asp.net

I have a system with a two-stage login.
Stage one is a Company Login which identifies the Company using my system.
Stage two is a Staff Login where a member of staff belonging to the above company logs in.
In both stage an option is offered to save certain login details (Location/Company but not password)
A user should be able, if they wish, to set the Company Login Cookie, but not the Staff Cookie, there is no need to set a Staff Cookie without a Company Cookie, although it doesn't really matter if they do!
Stage one login, amongst database checks etc does this:
If SaveCookie Then
Dim loginCookie As New HttpCookie("LogInCompany")
loginCookie.Values("database") = Database
loginCookie.Values("savedKey") = SavedKey
loginCookie.Values("samCompanyId") = CompanyId
loginCookie.Values("samCompanyName") = Common.htmlDecode(CompanyName)
loginCookie.Expires = Date.Now.AddDays(7)
HttpContext.Current.Response.Cookies.Add(loginCookie)
End If
Then stage two does this:
If SaveCookie Then
Dim loginCookie As New HttpCookie("LogInStaff")
loginCookie.Values("locationId") = locationID
loginCookie.Expires = Date.Now.AddDays(7)
HttpContext.Current.Response.Cookies.Add(loginCookie)
End If
Obviously they are entirely separate functions, so I don't think the variable naming being the same is the issue.
What happens is:
Company Login successful > Company Cookie is Saved, User proceeds to
User Login User Login > User Cookie is Saved, BUT the Company Cookie
is deleted.
This is using Chrome, I haven't checked other browsers but Chrome is the most important to me.
I know that this is definitely what is happening as I have checked in the Chrome Console, the Cookies are added and removed as per description above.
Can someone help point out where I am going wrong here?
EDIT - Nothing wrong with this code!
Argh... after a day of messing about with this, it turns out that the Cookie was being cleared by an unexpected, and caught, error in a different, but related section of code! This question can be closed if required, or left ...?

ASP.NET see if member is online

I'm developing a ASP.NET site in umbraco, and I need to see if a member with a given ID is online. How can I do that?
So far, I've tried to get the member by so:
Member m = new Member(myID);
But how can I check, if the returned member is logged in or not?
EDIT: I followed the link, and extracted the following code from it:
var users = Membership.GetAllUsers();
foreach(MembershipUser user in users){
Response.Write(user.IsOnline.ToString() +"<br/>");
Response.Write(user.LastActivityDate.ToString() + "<br/>");
Response.Write(user.LastLoginDate.ToString() + "<br/>");
}
However, the returned result shows that the property isOnline is true for every member, even though they're not online. I'm aware that it is because of the fact that the LastActivityDate updates automatically whenever I access the user, as stated here: Is it possible to access a profile without updating LastActivityDate?. Unfortunately, I don't get the solution to that question.
I've also tried to access the member by:
MembershipUser m = Membership.GetUser('myID',false);
But even though I put false as the second parameter, the LastActivityDate still updates. How can I work around this? I should note that I work with ASP.NET v. 4.0 in umbraco 4.7 at a localhost.
Thanks!
:EDIT END
Best regards,
Brinck10
You can use the MembershipUser.IsOnline Property that show true if the current date and time minus the UserIsOnlineTimeWindow property value is earlier than the lastActivityDate for the user.
There is an example on the MSDN page.
relative:
Proper 100% IsOnline implementation for asp.net membership
How to check in ASP.NET if the user is online?
asp.net custom membership provider: IsOnline property
The solution to the problem:
(1) I made a costum field in the membertype called lastActivityDate.
(2) I placed a macro on the masterpage, update the member's lastActivityDate to the current time given that the member was online.
(3) On the validation page I checked if the lastActivityDate + CostumBuffer was bigger than DateTime.Now.
Thanks for your patience Aristos.

ASP.NET (MVC3) - HttpRuntime.Cache - key intermittently present

I have a really strange problem and I'm completely puzzled.
I have a piece of code that parses some data and stores the result in our webserver's HttpRuntime.Cache using the Insert method. This is stored for 10 seconds. There seem to be some problems so I created a test page that retrieves a simple object from the cache and displays if it is null or not. To add the object to the cache, I use:
HttpRuntime.Cache.Insert(CHECK_KEY, new object(), null, DateTime.Now.AddSeconds(10), System.Web.Caching.Cache.NoSlidingExpiration);
In a test page, I try to retrieve the object:
var isInCache = this.cacheService.Get<object>(CHECK_KEY) != null;
and the method of the cacheService is:
public T Get<T>(string key)
{
return (T)HttpRuntime.Cache.Get(key);
}
Now the strange part. If I call a URL that calls the 'Insert' method, and go to my test page to retrieve it, the value of isInCache is false in about 99% of the time. Sometimes it works correctly for the whole 10 seconds (e.g. I refresh my test page every second and I get true 10 times) but again, most of the time it just returns false.
Now, when I keep F5 pressed, I sometimes see true in my output, in the blink of an eye, which means that the key CAN be found! This is not some browser cache, because it will only flash true intermittetly for the 10 seconds of cache duration, after which is it will only display false (which is logical, since the key is expired). So my question is:
WHY will retrieving a simple object from the cache fail most of the time?
There are other items in the cache (on the same test page) that do get retrieved, just not that object.
To make things worse, this (of course!) works flawlessly on my local machine, on the test machine, just not production. I'm pretty clueless. Please help :-)
EDIT:
Ok so I'm now testing in two different browsers, IE9 and Chrome... and IE9 is correctly showing the items in the HttpRuntime.Cache but Chrome is NOT. It shows always false and no other cached data, except when keeping F5 pressed it will occassionally show it. Since when is HttpRuntime.Cache browser dependant???
Extra edit: IE9 shows no more cached data. So while it can differ across browsers, it's not that IE will always work and chrome not... it differs.
EDIT2:
So I'm passing the variables to my view using ViewData:
ViewData["machineName"] = machineName;
ViewData["isInCache"] = isInCache;
ViewData["A"] = A;
ViewData["B"] = B;
Machinename comes from Server.MachineName, isInCache is the object, variable A is not from the HttpRuntime.Cache, variable B does, which is also intermittently not present.
After much debugging and thought, it appeared that the hosting provider had the 'Maximum Worker Processes' in IIS 7 Application pool settings to a value larger than 1. The HttpRuntime.Cache is not shared in a web farm, thus it could well be that I hit the 'wrong' instance which did not have the object cached. Continuously pressing F5 would have me occassionaly hit the instance which did have the value cached.

ASP.NET - Log User Session Start/End Times for Audit Trail - Global.ASAX?

My ASP.NET intranet web application uses Windows Authentication, and I would like to record the following details:
1) Windows ID
2) Session Start Time
3) Session Stop Time
4) URL being browsed to (optional)
I've got some basic code setup in "Session_Start" method of the Global.ASAX to log session start times (seen below), but that's it so far. I have the feeling this is a primitive approach and there are "better" ways of doing this. So I really have two questions:
1) Is this the right way to go about doing this? If not what are some other options?
2) If this is the right way, do I just need to drop some code in the "Session_End" method to record the time they exit, and thats a complete solution? Does this method always get called when they close the browser tab they have the site open in, or do they have to close the entire browser (I don't have logout functionality)? Any way users can skip over this session end method (or start for that case)?
Dim connsql As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("MyConnectionstring").ConnectionString)
Dim cmdsql As System.Data.SqlClient.SqlCommand = connsql.CreateCommand
cmdsql.CommandText = "BeginUserSession"
cmdsql.CommandType = Data.CommandType.StoredProcedure
Try
cmdsql.Parameters.Add("#windowsid", System.Data.SqlDbType.VarChar, 30, "windowsid")
cmdsql.Parameters("#windowsid").Value = Session("UserInfo").identity.name
If connsql.State <> System.Data.ConnectionState.Open Then connsql.Open()
cmdsql.ExecuteNonQuery()
connsql.Close()
Catch ex As Exception
Finally
If connsql.State <> Data.ConnectionState.Closed Then connsql.Close()
End Try
'Stored Proc records start time
Session_End is not reliable.
What I would suggest is on Session_Start you create a record that notes the time the Session was created, and in Session_End you update the record with the time it was ended.
To handle the majority of sessions which are passively abandoned, use Application_BeginRequest to update the record to note when the user was "last seen".
You will then need to determine a way of marking sessions that have been passively abandoned. This will be site/app specific. It could be as simple as picking a number of minutes that must pass before the session is considered abandoned - like 10 minutes.
So then you have a query:
SELECT Username,
SessionStart,
SessionEnd,
LastSeenOn,
DATEDIFF(mi, SessionStart, ISNULL(SessionEnd, LastSeenOn)) DurationMinutes
FROM SessionAudit
WHERE SessionEnd IS NOT NULL
OR DATEDIFF(mi, LastSeenOn, getdate()) > 10
Which will bring back your session audit log.
Your approach could be described as simple, but that could be totally fine - it comes down to what the requirements are. If you need to log a full suite of application errors and warnings, look at implementing something like Log4Net. Otherwise I wouldn't say there is anything wrong with what you are doing.
Sessions are ended when there has been no user activity for the amount of time specified in the timeout value, or when you explicitly call Session.Abandon() in your code. Because of the stateless nature of HTTP, there is no way to tell if a user has left your site, closed the browser or otherwise stopped being interactive with their session.
I am not sure you can catch the end of the session accurately because
The user can close their browser and that will not necessarily end the session.
They can then go back to your site and thus may have multiple sessions.
You can try messing with setting in IIS to kill the session very quickly after inactivity but its not a good idea.
Also... If the users are not all on an internal network you will have no control as to whether they have a "Windows ID" or not.

Resources