How to make sure the user just logged in? - asp.net

I have a web control panel with links to sensitive informations (like credit card number).
When the user clicks (who got logged in before) on one of these link, I need to check his credntials.
How can I make sure on the server side when he requests ("/sensitive-informations.aspx") that he just entered his credentials ?
EDIT : the main problem here is the "he just entered his credentials" , I need to make sure that he comes DIRECTLY from the login page.

There are a few ways to do this. For instance, after the user enters his credentials, save them in the Session object.
Then, in the Page_Load of sensitive-informations.aspx make sure the Session object exists.
To better illustrate this:
In your login.aspx.cs page:
protected btnLoginClick(...)
{
// CHECK USERNAME and PASSWORD
if (UserIsAuthenticated)
{
Session["UserName"] = user;
}
}
Then in your sensitive-informations.aspx.cs
protected page_load(...)
{
// If UserName doesn't exist in Session, don't allow access to page
if (Session["UserName"] == null)
{
Response.Redirect("INVALID_USER.aspx");
}
}
Edit:
Based on OPs comments, if you want to know which page you came from, you can either use:
Page.PreviousPage like this:
protected void Page_Load(object sender, EventArgs e)
{
var x = this.Page.PreviousPage;
Or use Request.UrlReferrer like this:
protected void Page_Load(object sender, EventArgs e)
{
var x = Request.UrlReferrer;
In both cases make sure x isn't null first...

You can check the UrlReferrer in the Page_Load event of sensitive-informations.aspx:
if (Request.UrlReferrer != null)
{
if (Request.UrlReferrer.AbsolutePath.ToLower().Contains("you-login-page"))
{
//User came from the login page
}
}
UPDATE
Based on your comment, you should check the LastLoginDate property of the MembershipUser class
This will give you the, well, last login date of the current user. You can compare that with the current date/time to make sure that the user "just entered their credentials". Couple this with the checking where the user came from (either with Request.UrlReferrer or Page.PreviousPage).

Related

Session created after the postback occured and page-load event doesnt use session correctly in ASP.NET

I’ve made a handy “user control” for login to my website and it is placed in the site master.
The natural procedure is that the user logs in the web site and he should be announced with a welcome message containing its full name. The full-Name naturally should sits in a session variable created when the user logged on.
There is no doubt that we place the desired code in the “page_load” event and expect it to pass user’s full-name to the right circumstances (here its a label named lblFullName) in order to print/show the welcome message when login button clicked, But the full-name doesn’t passed until the user logs in the website again (for the 2nd times).
Why this problem happens?
Its some part of my code:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["FullName"]==null)
{
//nothing 2 do.
}
else
{
lblFullName.Text = Session["FullName"].ToString();
}
}
You probably set the Session variable in the user control after the Page_Load event has been processed, so that it will not see the user name until the next postback.
In order to update the Label text as soon as the login is validated, you could:
Define an event in the user control
Register an event handler in the main page
Call the event handler as soon as the user has logged in
In the event handler, update the Label text
You could also eliminate the Session variable by passing the user full name in an EventArgs derived class. If you make the following class accessible in the user control and in the main form:
public class StringEventArgs : EventArgs
{
public string Value { get; set; }
public StringEventArgs(string value)
{
Value = value;
}
}
then you can define this event in the user control:
public event EventHandler<StringEventArgs> UserLoggedIn;
In the function where the login is confirmed, you call the event handlers:
private void UserLoginValidation()
{
// Login validation is done here
bool loginSuccessful = ...
if (loginSuccessful && UserLoggedIn != null)
{
UserLoggedIn(this, new StringEventArgs(fullName));
}
}
In the main page, you register the event handler, which updates the Label:
protected void Page_Load(object sender, EventArgs e)
{
loginUserControl1.UserLoggedIn += loginUserControl1_UserLoggedIn;
...
}
private void loginUserControl1_UserLoggedIn(object sender, StringEventArgs e)
{
lblFullName.Text = e.Value;
}

handling sessions on every page of website

I have a data driven website and the current users Id gets stored in Session["UserId"].So all the data that shows up in almost all the pages is user specific.and when a user is using the site anonymously,it is a different set of results that i show and has nothing to do with the UserId.
My problem is I have to check if the Session["UserId"] is not null at every line where I am using Session["UserId"] and i somehow feel that it is not the right way to do it.
Is there a way where I can check if the Session is not null on page_load? If my session turns out to be null, how do i handle it? the page won't even load at all.
I hope i was able to explain
Instead of check session on every of your pages, put the session control in a base class and make all your pages extends this class. Every time your page inits the Page_Init base method will check if user is authenticated. If it's not authenticated the method will throw an exception that will be catched by Page_Error method. This method will clear session resources and redirect to Default page.
Make a hyerarchical classes for session control:
public class UserSession { }
public class AnonymousSession : UserSession {}
On your Page Logon put the UserId on the session based on logon type:
bool isAnon = GetAnonymous(); // Check form page if login is anonymously
UserSession user;
if(isAnon)
user = new AnonymousSession();
else
user = new UserSession();
Session.Contents.Add("UserId", user);
Set a property in PageBase named Anonymously that tells you if user has entered anonymously, and use it in your pages to set the set results of each of your pages:
public class PageBase: System.Web.Ui.Page
{
// Check here if session type is anonymous
protected bool Anonymously
{
get
{
return (UserSession)Session.Contents["UserId"] is AnonymousSession;
}
}
protected void Page_Init(object Sender,System.EventArgs e)
{
var user = (UserSession)Session.Contents["UserId"];
if (user == null)
{
throw new SessionException();
}
}
protected void Page_Error(object sender, System.EventArgs e)
{
Exception ex = Server.GetLastError();
Server.ClearError();
if(ex is SessionException)
{
Context.Session.Clear();
Context.Session.Abandon();
FormsAuthentication.SignOut();
Server.Transfer("Default.aspx", true);
}
}
}

login validation on asp page

Since I'm a newbie for asp, I'm trying to take a name as input,trying to put that name in list, then check the list to find a match. I'm doing this as basics keeping the log in procedure in mind, which I will try to implement later. I have the following code:
I have made a class like this:
public class Login
{
public string name { get; set; }
}
The two button events are as follows:
List<Login> list;
protected void Button1_Click(object sender, EventArgs e)
{
list = new List<Login>(){
new Login { name = TextBox1.Text },
new Login { name = "Badhon"}
};
Label1.Text = "Inserted";
}
protected void btnLogIn_Click(object sender, EventArgs e)
{
foreach (var s in list)
{
if (s.name == TextBox1.Text)
{
Label1.Text = "Found";
break;
}
else
Label1.Text = "Not Found";
}
}
when I'm trying to insert,its working fine, but when clicking on the login button showing any error message like "Object reference not set to an instance of an object."
When you press the login button you're in a different scope to when you pressed the first button, so the list is not initialised (Each time you press an ASP button you get a new state: The web is designed to be stateless).
Why not use the asp:login control?
You code is not exactly what it is supposed to be. You'd better go searching for some (of the various) examples on how to hanle logins in ASP.NET.
Each click is a new HTTP request. The list initialized in the first request is not the same with the list in the other request because each request will use its own instance of the Page object.
You need to read & understand the life cycle of a ASP.net page: http://msdn.microsoft.com/en-us/library/ms178472.aspx
make protected properties to store list of logins
It should looks like this:
protected List<Login> LoginStore
{
get{ return ViewState["store"] =! null ? (List<Login>)ViewState["store"] : new List<Login>; }
set{ ViewState["store"]=value; }
}
You can use Session as well as ViewState. It will make your list doesn't disapear every time you make PostBack.
then in event btnLogIn
create List<Login> list = LoginStore;
then make the rest of your code.
click on here
why do go forloop, use session variables in Global.asax, try googlin you can find many example..

How to See List of Active Users Stored in Session Objects on the Admin Page

What i am doing is whenever users logs in I store his username in Session Object
Now what i want on the Admin Page is the List of ACTIVE USERS (i.e No of Users which are presently working with the Application (usernames in Session Objects)
Is there any way of doing that..
???
Thanks
Based on your comment to Davide Piras, if you are storing Session["user"] =username then you are only storing one element since you are always using the same key.
I would put everything in a List<string>, for example.
Something like this in your login page:
List<string> activeUsers = Cache["ActiveUsers"] as List<string>;
if(activeUsers==null)
activeUsers = new List<string>();
activeUsers.Add(username_of_person_logged_in);
Cache["active_users"]=activeUsers;
Then in your "Admin" page...
List<string> activeUsers = Cache["ActiveUsers"] as List<string>;
if(activeUsers!=null)
{
foreach(var item in activeUsers)
{
//do something with them
}
}
Note: I changed it to Cache since Cache is shared across all users. Session will not work since it will be only valid on a per-user basis. Thanks to #CheckRaise for his comment.
The Session object cannot be accessed outside of its own session. If you need an administrator to be able to see all the active sessions, you need to use the Application object. For example, in global.asax:
protected void Application_Start(object sender, EventArgs e) {
Application["Users"] = new List<string>;
}
Then, to add a user (possibly when they click 'Log in'):
Application.Lock();
((List<string>)Application["Users"]).Add(username);
Application.UnLock();
You should also remove the user in Session_End:
protected void Session_End(object sender, EventArgs e) {
Application.Lock();
((List<string>)Application["Users"]).Remove(username);
Application.UnLock();
}

Detect browser refresh

How can I find out if the user pressed F5 to refresh my page (Something like how SO implemented. If you refresh your page, the question counter is not increased). I have tested many code snippets mentioned in a dozen of tutorials, but none worked correctly.
To be more clear, suppose that i have an empty web form and would like to detect whether the user has pressed F5 in client-side (causing a refresh not submit) or not.
I can use session variables, but if the user navigates to another page of my site, and then comes back , I'd like to consider it as a new visit, not a refresh. so this is not a session-scope variable.
Thanks.
Update: The only workaround I could find was to inherit my pages from a base page, override the load method like below:
public class PageBase : System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.Session["LastViewedPage"] = Request.RawUrl;
}
}
and in every page if I was interested to know if this is a refresh:
if (this.Session["LastViewedPage"].ToString() == Request.RawUrl)
{
// This is a refresh!
}
I run into this problem and use the following code. It works well for me.
bool isPageRefreshed = false;
protected void Page_Load(object sender, EventArgs args)
{
if (!IsPostBack)
{
ViewState["ViewStateId"] = System.Guid.NewGuid().ToString();
Session["SessionId"] = ViewState["ViewStateId"].ToString();
}
else
{
if (ViewState["ViewStateId"].ToString() != Session["SessionId"].ToString())
{
isPageRefreshed = true;
}
Session["SessionId"] = System.Guid.NewGuid().ToString();
ViewState["ViewStateId"] = Session["SessionId"].ToString();
}
}
The only sure solution is to make a redirect to the same page , and here is a similar question: Post-Redirect-Get with ASP.NET
But there are also some other tricks, by adding some ticket on the page and see if this is the same or have change, see the full example and code at:
http://www.codeproject.com/Articles/68371/Detecting-Refresh-or-Postback-in-ASP-NET
and one more:
http://dotnetslackers.com/community/blogs/simoneb/archive/2007/01/06/Using-an-HttpModule-to-detect-page-refresh.aspx

Resources