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.
Related
I have a question about empty session and "try-catch" handling.
I have few forms that use a session to pass data one to each other and sometime when the user is stay for a long time on specific page he cannot continue to the next page because the session is empty.
I want to handle it somehow but i have no idea.
On page load of the next page, check if the user has valid session, if not then redirect to the login page.
Suppose you store user's login id in LoginID field of the session, then you can check as following
if(Session["LoginID"]==null || Convert.ToString(Session["LoginID"])==string.Empty)
{
//Redirect to login page
}
Session is a collection.
You can use its Count property.
if(Session.Count == 0)
{
// session is empty
}
I'm using asp.net Membership, I develop an admin page who can regenerate a temp password to send to the user, then when the user log on for first time, the password must be changed, but I cant figure out who to know if the password was reseted.
I tried something like in a base controller:
if (user.LastPasswordChangedDate >= user.LastLoginDate)
{
filterContext.Result = RedirectToAction("ChangePassword", "Account");
}
But, I already have updated the LastLoginDate because the ChangePassword Action need to be with a autenticated user.
I was thinking when reseting the password to lock/unlock the user to get updated the "LastLockoutDate" and do:
if (user.LastPasswordChangedDate >= user.LastLockoutDate)
{
filterContext.Result = RedirectToAction("ChangePassword", "Account");
}
But, I can't find a method to do manual lockout
Thanks!!!
There's a lot of things you could do, some would depend on how your system works. For instance, you could store a specific piece of data in the Comment field, if you're not using comments.
Or, if you don't use the "Approved" bit (that is, when you create new users you do not require them to validate an email or something, but instead create them with IsApproved set to true) then you can set IsApproved to False and force a password change if it's false.
There is no method to access much of this data in the Membership API, you just have to access it from you database.
You could also store this in the Personalization provider.
Another option is to simply avoid storing this in the Membership database, and instead just add a table or a field in your apps data to deal with this.
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.
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.
I have a form. On submit of a button, it inserts a record into the db. If I go back in my browser and refresh the page it's resubmitting it causing all sorts of issues as you can imagine. How do I ensure that the user can't refresh the previous page and the state of that page does another automatic submit on refresh like this?
I'm not using ViewState. I actually have it disabled in the page directive
No, Response.Redirect does NOT solve this problem. The user can still go back with the browser's back button and refresh at the point where they submitted and it will still run the button's event sending the data downstream to my DL insert
The solution I use most often is this:
When the user first visits the page (Non-PostBack), generate a token value (GUID is easy). Take this token value and store it in their Session variables and a hidden field in the page. Being a field, this value should persist through round trips to the server without ViewState enabled (I could be mistaken on that count, so please check it!). Should the page be refreshed (and form values lost), a new value will be generated by the Non-PostBack initialization.
When the page is posted back, retrieve the hidden field value and compare it against the expected value in the user's Session variables:
If the tokens match, accept the submission as "genuine", remove the token from the Session variables, and continue your workflow.
If the token is missing from Session variables, the user is trying to submit the form again. - If the tokens do not match, the user is "replaying" an old submission of the form.
Example code to achieve this sort of solution:
public partial class MyPage : Page
{
protected HiddenField tokenField;
protected void Page_Load()
{
if(!IsPostBack)
CreateToken();
}
// Call this method to establish a token in session and on the page.
private void CreateToken()
{
string token = new Guid().ToString();
Session["dupeToken"] = token;
tokenField.Value = token;
}
// Call this method to validate the token before continuing workflow.
private bool TokenIsValid()
{
string expectedToken = (string)Session["dupeToken"];
if(expectedToken == null)
return false;
string actualToken = tokenField.Value;
return expectedToken == actualToken;
}
// Call this method when the page submission is complete to prevent re-submission.
private void ConsumeToken()
{
Session["dupeToken"] = null;
}
}
The easiest way would be to wrap the form in an < asp:UpdatePanel>. That way, all postbacks are done via AJAX and the browser will never ask you to re-submit your form.
The best two ways of doing this are:
Performing a check on a distinct field against the database
Create a hidden token in the form that uses a salt based on time. If you put logic in script to check for the existing time and compare it to the token, you can either allow the submission or define it. For example, if the form is drawn at a certain time, you store the token, and within 30-60 seconds you can submit, but after that you cannot.