Session timed out when POST/GET. Allow login, then post data - asp-classic

Classic asp.
Sometimes the session has timed out while the user has filled out a large form.
Currently the user just gets "you are not logged in", and the login-form.
When the user logs in again, (s)he have to start over, and navigate to the previous form to fill it out again.
I'd like to just submit the formdata again, if the user logs in successfully.
There a many forms/pages in the system, so the login-check is in a common include-file.

Hi Leif Session time is for Server to control the data keeping time , maybe you can use cookie for your issue because it is controlled by Client(Browser). hopefully my idea can help you ,thanks willie

Classic ASP, our "One Way" posting code.
I set a cookie and save the cookie to the members table.
The cookie doesn't need to be anything fancy, date, name, IP, session works just fine. Encode them SHA256 with a Salt.
The idea is to use this special cookie if on a forms page and their user session has been lost or timed out.
Basic setup: (Not complete code just enough to get the idea and flow)
Login page.
Create SHA256 Hash
Save as Cookie
SetKeysCookie "CookieName","LostSession",strSHA256Hash,mysite.ext,"1"
Sub SetKeysCookie(strCookieName,strCookieKey,strCookieValue,strCookieDomain,strCookieExpires)
Response.Cookies(strCookieName).Expires = DateAdd("d",strCookieExpires, Now())
Response.Cookies(strCookieName).Domain = strCookieDomain
Response.Cookies(strCookieName).Path = "/"
Response.Cookies(strCookieName)(strCookieKey) = strCookieValue
Response.Cookies(strCookieName).Secure = True
End Sub
Optional: I use the HTTP_Cookie which would be as follows.
Sub SetKeysCookieHttpOnly(strCookieName,strCookieKey,strCookieValue,strCookieDomain,strCookieExpires)
strGMTDateRFC22 = CookieServerUTC("d","&strCookieExpires&",5,"GMT") ' 1 Day set in char enc dec page
Response.AddHeader "Set-Cookie", strCookieName & "=" & strCookieKey & "=" & strCookieValue & "; expires=" & strGMTDateRFC22 & "; domain="& strCookieDomain &"; path=/;"
End Sub
Update members database:
UPDATE Member SET LostSession='"&strSHA256Hash&"' WHERE ID = "&id&"" .....
On forms page:
Check Session on Post... If Session = NULL then
Check if Cookie is set.
Get the cookie
Old method: Request.Cookies("CookieName")("LostSession")
New HTTP_Cookie
strCookieX = Request.ServerVariables("HTTP_COOKIE")
If InStr(strCookieX,"LostSession=") Then
j = InStrRev(strCookieX, "LostSession=")
if j > 0 Then
strCookieTEMP = Mid(strCookieX, j+12)
end if
j = 64
if j > 0 Then
strCookieTEMP = Left(strCookieTEMP, j-0)
End If
strCookie = strCookieTEMP
End If
The above will pull all your HTTP cookies and then search for your LostSession cookie.
Because we know the fixed length we can pull it cleanly.
Next on the form we check to see which member this cookie is assigned to.
strSQL = "SELECT TOP 1 "
strSQL = strSQL & " ID,Email,ClientID,LostSession"
strSQL = strSQL & " FROM Members "
strSQL = strSQL & " WHERE LostSession = '"&strCookie&"' "
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open strSQL,Conn,3,3
If rs.EOF=False Then
Session("id") = rs("ID")
End If
rs.Close
Set rs = Nothing
When found, we set the minimum Session Variables to allow this post to complete.
Session("id") or Session("authorized") whatever you need to complete the post.
At the end of the post, as we successfully submitted the form we now can send the session failed user to the login page.
Session.Abandon
sRedirectPage = "https://domain.ext/logout.asp"
Response.Status="403.6 IP Restricted"
Response.AddHeader "Location",sRedirectPage
Response.end
You should be able to see the different parts of the http cookie method of saving a session that has timed out.
If you need anything just ask.
Murray

My solution is, in the header file included on all pages, if the user is logged out, create a form with all post and get values hidden, and the username/password field visible.
User then re-enters the username and password, and submits the form.
If the user is then succesfully logged in, the script continues and processes the data.
It will not work for uploads, but this is rarely used anyway.

Related

update Master page label with username without pulling from session

On my site I display a logged in username on the master page (in a label) this is done as below, by pulling the username from the session object and putting it into the label on the master page, page_init page event. My problem is that I am bypassing the session now because of timeout issues i wont bore you all with but now I need to change the code to pop the username into the master page label once, then not try and access the session again as it clears after around 10 minutes due to the IIS pool. I realise i could open a new connection to the database each time the master page loaded to retrieve the user name but I thought there might be an easier way than that. any help would be really appreciated.
Protected Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
txtUserInfo.Text = (Session("name") & " [ " & Session("org") & " ]")
End Sub
For the user name alone Humpy's reply would suffice (assuming the thread principal/identity is populated correctly). If you need more bits of information you could use cookies:
After login, set the cookie with a reasonable expiration:
Response.Cookies["userInfo"]["name"] = "currentUsername";
Response.Cookies["userInfo"]["org"] = "currentOrg";
Response.Cookies["userInfo"].Expires = DateTime.Now.AddDays(1);
On subsequent requests you can pull the data out of the cookie:
if(Request.Cookies["userInfo"] != null)
{
HttpCookie c = Request.Cookies["userInfo"];
txtUserInfo.Text = Server.HtmlEncode(c["name"]) & " [" & Server.HtmlEncode(c["org"]) & "]";
}
See here for more details: http://msdn.microsoft.com/en-us/library/ms178194.ASPX
You should be able to use..
txtUserInfo.Text = User.Identity.Name;
This is how I use mine. Once the user logs in, displays the user's names perfectly. Hope this helps!

ASP.net Coding User Roles into Login Page

I've developed a login page, which functions off of a stored procedure. The login part functions well, however, the website will consist of roles that will determine what page the user is directed to once they are logged into the secure section. The columns I’m focusing on in the database / table are:
Guid -0 column
Login_name -9th column
Login_Pwd -10th column
Role_ID -11th column / Contains a value of 1 or a 2
What I’m trying to do is: get the login page to distinguish between the users with a Role_ID of 1 and those that have a Role_ID of 2. But, currently, when I log into the page, I’m directed to the SecurePage.aspx regardless of what Role ID the user has. Could I please get some direction on this?
This is my Stored Procedure:
ALTER PROCEDURE [dbo].[Check_Users]
#Login_name as varchar(100),
#Login_Pwd as varchar(50)
AS
/* SET NOCOUNT ON */
SELECT * FROM SupplierCompany WHERE Login_name=#Login_name AND Login_Pwd=#Login_Pwd
RETURN
This is the code behind my login button:
Try
Dim con As New SqlConnection(GetConnectionString())
con.Open()
Dim cmd As New SqlCommand("Check_Users", con)
cmd.CommandType = CommandType.StoredProcedure
Dim p1 As New SqlParameter("Login_name", username.Text)
Dim p2 As New SqlParameter("Login_Pwd", password.Text)
cmd.Parameters.Add(p1)
cmd.Parameters.Add(p2)
Dim rd As SqlDataReader = cmd.ExecuteReader()
If rd.HasRows Then
rd.Read()
lblinfo.Text = "You are Authorized."
FormsAuthentication.RedirectFromLoginPage(username.Text, True)
Response.Redirect("securepages/SecurePage.aspx")
Else
lblinfo.Text = "Invalid username or password."
End If
'check the Role of the usre logging in
While (rd.Read())
Session("numrecord") = rd.GetValue(0).ToString()
rd.GetValue(11).ToString()
If rd.GetValue(11).ToString() = 1 Then
Response.Redirect("securepages/SecurePage.aspx")
ElseIf rd.GetValue(11).ToString() = 2 Then
Response.Redirect("securepages/newShipment.aspx")
End If
End While
Catch
Finally
End Try
..Any assistance is greatly appreciated.
Inside your If rd.HasRows Then you redirect to the SecurePage, so I'm guessing it doesn't even reach the while. Try removing the Response.Redirect("securepgaes/SecurePage.aspx") inside this if, and adding the while loop there, like this:
If rd.HasRows Then
rd.Read()
lblinfo.Text = "You are Authorized."
FormsAuthentication.RedirectFromLoginPage(username.Text, True)
'Response.Redirect("securepages/SecurePage.aspx") Remove this line
'check the Role of the user logging in
While (rd.Read())
Session("numrecord") = rd.GetValue(0).ToString()
rd.GetValue(11).ToString()
If rd.GetValue(11).ToString() = 1 Then
Response.Redirect("securepages/SecurePage.aspx")
ElseIf rd.GetValue(11).ToString() = 2 Then
Response.Redirect("securepages/newShipment.aspx")
End If
End While
Else
lblinfo.Text = "Invalid username or password."
End If
Where have you defined the code to redirect the logged in user?
The Login control by default will try and redirect you to a destination page once successful. I would think you should hook in to the OnLoggedIn event and redirect the page before the server has a chance to do it for you.
As an alternative if that doesn't work you could try building your own 'Login Control' - since you are using a stored procedure to validate users anyway, it's not a huge leap to dump a few textboxes on the page and go that way. At least then you don't need to worry about overriding the default behaviour. I believe ASP.NET provides a bunch of SPs you can use which will validate user passwords and such - check it out on the server (they are all like dbo.aspnet_*.

Display Message to user and then abandon Session

I have added Two Factor Authentication to my Mobile ASP.Net Web App. When the user successfully enters their User Name and Password then a pin number is emailed to their email address which is stored in the database. The issue I am having is that after notifying the user that they don't have an email defined and then reload the login page but my code isn't notifying the user rather it is just reloading the Login.aspx page:
Private Sub GeneratePin()
Dim r As New Random(System.DateTime.Now.Millisecond)
_Pin = CStr(r.Next(1000, 99999))
_email = CIAppGlobals.CurrentUser.UsrContactEmail
With lblPin
.Text = "PIN has been emailed to the you please check your email now."
End With
If Not String.IsNullOrEmpty(_email) Then
Dim Message As String = " Your Mobile PIN number is " & _Pin & vbNewLine & "From IP Address: " & CIAppGlobals.AppSettings.ClientIP
Tools.SendEmail(CIAppGlobals.CurrentUser.UsrContactEmail, "Mobile App - Two Factor Authentication", Message)
Else
Dim sText As String = "Please contact the Administrator You do not have an email address defined within Application."
'DirectCast(HttpContext.Current.Handler, System.Web.UI.Page).ClientScript.RegisterStartupScript(Me.[GetType](), "test", "alert('" & sText & "')", True)
Response.Write("<script>alert('" & sText & "');</script>")
Thread.Sleep(5000)
'Session.Abandon()
'FormsAuthentication.SignOut()
Response.Redirect(ParentFolder & "/Login.aspx")
End If
End Sub
Your call to Response.Redirect() is causing anything you output not to be displayed. You need to remove that, then output a link or some javascript to go to the login page.
Also: you need to remove the call to Thread.Sleep(). That is causing a needless delay and keeping an asp.net thread busy doing nothing. It's not doing what you think it is...

How to Make Very Simple ASP.Net Password Protected Page

I am looking for a very simple solution to password protect an ASP.Net page.
I found exactly what I am looking for here but it is in ASP and I do not know the syntax to convert it to ASP.Net.
It simply creates a temporary cookie that will expire as soon as they close their browser window.
I am not looking to store the username / password in a db. I will manually change the password occasionally.
Simply helping me convert the following code to ASP.Net would be wonderful!
This goes on the logon.aspx page and pulls values from a form.
Username="Administrator"
Password="Admin"
Validated = "OK"
if Strcomp(Request.Form("User"),Username,1)=0 AND Request.Form("password") = Password then
Response.Cookies("ValidUser") = Validated
If (Request.QueryString("from")<>"") then
Response.Redirect Request.QueryString("from")
else
Response.Redirect "MyPage.aspx"
End if
Else
If Request.Form("User") <> "" then
Response.Write "<h3>Authorization Failed.</h3>" & "<br>" & _ "Please try again.<br> <br>"
End if
End if
This goes on the password protected page to confirm the cookie was created.
Validated = "OK"
if Request.Cookies("ValidUser") <> Validated then
dim s
s = "http://"
s = s & Request.ServerVariables("HTTP_HOST")
s = s & Request.ServerVariables("URL")
if Request.QueryString.Count > 0 THEN
s = s & "?" & Request.QueryString
end if
Response.Redirect "Logon.aspx"
End if
Just use the built-in forms authentication and setup your credentials store in the web.config.
Here's a quick and dirty example
Another example

Issue Querying LDAP DirectoryEntry in ASP.NET

I have users login to my application via Active Directory and then pull from their AD information to garner information about that user like so:
Dim ID as FormsIdentity = DirectCast(User.Identity, FormsIdentity)
Dim ticket as FormsAuthenticationTicket = ID.Ticket
Dim adDirectory as New DirectoryEntry("LDAP://DC=my,DC=domain,DC=com")
Dim adTicketID as String = ticket.Name.Substring(0, 5)
Session("people_id") = adDirectory.Children.Find("CN=" & adTicketID).Properties("employeeID").Value
Session("person_name") = adDirectory.Children.Find("CN=" & adTicketID).Properties("displayName").Value
Now, I want to be able to impersonate other users...so that I can "test" the application as them, so I added a textbox and a button to the page and when the button is clicked the text is assigned to a session variable like so:
Session("impersonate_user") = TextBox1.Text
When the page reloads I check to see if Session("impersonate_user") has a value other than "" and then attempt to query Active Directory using this session variable like so:
If CStr(Session("impersonate_user")) <> "" Then
Dim adDirectory as New DirectoryEntry(LDAP://DC=my,DC=domain,DC=com")
Dim adTicketID as String = CStr(Session("impersonate_user"))
Session("people_id") = adDirectory.Children.Find("CN=" & adTicketID).Properties("employeeID").Value
Session("person_name")= adDirectory.Children.Find("CN=" & adTicketID).Properties("displayName").Value
Else
[use the actual ticket.name to get this info.]
End If
But this doesn't work. Instead, it throws an error on the first Session line stating, "DirectoryServicesCOMException was unhandled by user code There is no such object on the server."
Why? I know I'm giving it a valid username! Is something strange happening in the casting of the session? The code is essentially the same between each method except that in one method rather than pulling from ticket.Name I pull from a session variable for the login I'll be looking up with AD.
Maybe the identity your process is running under needs permissions to access the active directory. You could do this by changing the identity your application runs under in the IIS application pool.
What is entered in the textbox?

Resources