update Master page label with username without pulling from session - asp.net

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!

Related

"Validation of viewstate MAC failed" only when posting back from a mobile browser that has been idle for sometime

I know that this question has been asked frequently on StackOverflow but my case is a bit different. I checked all the answers related to this issue and none solved my problem as in my case it only happens with browsers on mobile devices.
I only get the "Validation of ViewState MAC failed" error when posting back from a mobile browser that has been left open for some time. The error never appears when submitting a form from a computer browser. It neither appears when submitting from a mobile browser most of the time. It only appears when I open a mobile tab that was already submitted from some time and click the submit button again.
However, It happens all the time as well when I close my browser (so that it is not running in the mobile background), open it again and re-submit the form. I guess this is the main problem behind this error (re-launching the browser is causing page-reload on mobile before clicking on anything).
I tried the below solutions and none of them worked:
Manually set MachineKey to my web.config
Use aspnet_regiis utility to run the managed application where machine keys will be persisted.
Solutions proposed in this article
set LoadUserProfile = True in the application pool
Set the SessionTimeout = 0 in IIS application pool.
Secured my cookies over http.
Note: I know that setting enableViewStateMac="false" in my web.config will solve my problem, but I really don't wish to do so to avoid security depreciation in my application.
After a couple of tests, I noticed that the error only generates when the mobile browser force-reload/relaunch the page. For example, if I re-submit the form that has been already submitted from a mobile, most of the times it does not generate an error. However, sometimes, when I open the browser on the mobile, it force-reload/relaunches the page before I click on anything. Now when I click on the submit button, the error appears.
Possibly, this force-reload/relaunch is causing this error since the ViewState is being altered.
Another possibility is that the mobile is expiring the sessions even though I've set the sessions to not expire in my IIS.
Yet, another possibility would be that the mobile does not allow the browser to run in the background resulting in force-reload to re-construct the page when the user opens the browser again.
I am using the below code in my application:
Partial Class MasterPage
Inherits System.Web.UI.MasterPage
Private Const AntiXsrfTokenKey As String = "__AntiXsrfToken"
Private Const AntiXsrfUserNameKey As String = "__AntiXsrfUserName"
Private _antiXsrfTokenValue As String
Protected Sub Page_Init(sender As Object, e As EventArgs)
' The code below helps to protect against XSRF attacks
Dim requestCookie = Request.Cookies(AntiXsrfTokenKey)
Dim requestCookieGuidValue As Guid
If requestCookie IsNot Nothing AndAlso Guid.TryParse(requestCookie.Value, requestCookieGuidValue) Then
' Use the Anti-XSRF token from the cookie
_antiXsrfTokenValue = requestCookie.Value
Page.ViewStateUserKey = _antiXsrfTokenValue
Else
' Generate a new Anti-XSRF token and save to the cookie
_antiXsrfTokenValue = Guid.NewGuid().ToString("N")
Page.ViewStateUserKey = _antiXsrfTokenValue
Dim responseCookie = New HttpCookie(AntiXsrfTokenKey) With {
.HttpOnly = True,
.Value = _antiXsrfTokenValue
}
If FormsAuthentication.RequireSSL AndAlso Request.IsSecureConnection Then
responseCookie.Secure = True
End If
Response.Cookies.[Set](responseCookie)
End If
AddHandler Page.PreLoad, AddressOf master_Page_PreLoad
End Sub
Protected Sub master_Page_PreLoad(sender As Object, e As EventArgs)
If Not IsPostBack Then
' Set Anti-XSRF token
ViewState(AntiXsrfTokenKey) = Page.ViewStateUserKey
ViewState(AntiXsrfUserNameKey) = If(Context.User.Identity.Name, [String].Empty)
Else
' Validate the Anti-XSRF token
If DirectCast(ViewState(AntiXsrfTokenKey), String) <> _antiXsrfTokenValue OrElse DirectCast(ViewState(AntiXsrfUserNameKey), String) <> (If(Context.User.Identity.Name, [String].Empty)) Then
Throw New InvalidOperationException("Validation of Anti-XSRF token failed.")
End If
End If
End Sub
Private Sub MasterPage_Load(sender As Object, e As EventArgs) Handles Me.Load
'Add Base Path and Canonical URL
Dim strBasePath = "<base href='" & AppSettings("LivePath") & "' />"
Page.Header.Controls.Add(New LiteralControl(strBasePath))
End Sub
End Class
I hope there is a solution to this since I don't want to end up setting enableViewStateMac="false" in my web.config
[Update]
Potential Solution:
My current potential solution for this is to handle the "Validation of ViewState MAC failed" error and prompt a custom message to the user explaining the form validation failure. This way security and usability is balanced.
I was inspired by this article for this likely short-lived solution.

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

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.

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?

Get Session to expire gracefully in ASP.NET

I need a way to tell ASP.NET "Kill the current session and start over with a brand new one" before/after a redirect to a page.
Here's what I'm trying to do:
1) Detect when a session is expired in the master page (or Global.asax) of an ASP.NET application.
2) If the session is expired, redirect the user to a page telling them that their session is expired. On this page, it will wait 5 seconds and then redirect the user to the main page of the application, or alternatively they can click a link to get there sooner if they wish.
3) User arrives at main page and begins to use the application again.
Ok, so far I have steps 1 and 2 covered. I have a function that detects session expiry by using the IsNewSession property and the ASP.NET Session ID cookie value. if it detects an expired session it redirects, waits five seconds and then TRIES to go to the main page.
The problem is that when it tries to redirect, it gets to the part in the master page to detect an expired session and it returns true. I've tried calling Session.Abandon(), Session.Clear(), even setting the session to NULL, with no luck.
Someone out there has had to have faced this problem before, so I'm confident in the community to have a good solution. Thanks in advance.
The problem you are describing happens because asp.net is reusing the sessionid, if the sessionid still exists in the auth cookie when you call abandon() it will just reuse it, you need to explicitly create a new sessionid afaik something like:
HttpCookie mycookie = new HttpCookie("ASP.NET_SessionId");
mycookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(mycookie);
For ASP.NET MVC this is what I'm doing with an action method.
Note:
Returns a simple view with no other resources that might accidentally re-create a session
I return the current time and session id so you can verify the action completed succcessfully
public ActionResult ExpireSession()
{
string sessionId = Session.SessionID;
Session.Abandon();
return new ContentResult()
{
Content = "Session '" + sessionId + "' abandoned at " + DateTime.Now
};
}
The code in your master page, which detects an expired session and redirects, should look like this:
if (Session != null
&& Session.IsNewSession
&& Request.Cookies["ASP.NET_SessionId"] != null
&& Request.Cookies["ASP.NET_SessionId"].Value != "")
{
Session.Clear();
Response.Redirect(timeoutPageUrl);
}
Calling session.Clear() before redirecting ensures that on the subsequent page, Session.IsNewSession will be false.
Also note that I am checking for an empty string in the value of of the ASP.NET_SessionId cookie. This helps to prevent a logout from being mistaken as an expired session, if you happen to call Session.Abandon() in your logout process. In that case, make sure you expire the old session cookie as a part of the logout process:
Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.MinValue;
The adding the cookie trick worked for me also, as follows:
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs when a new session is started
If Session.IsNewSession Then
'If Not IsNothing(Request.Headers("Cookie")) And Request.Headers("Cookie").IndexOf("ASP.NET_SessionId") >= 0 Then
If Not IsNothing(Request.Headers("Cookie")) AndAlso Request.Headers("Cookie").IndexOf("ASP.NET_SessionId") >= 0 Then
'VB code
Dim MyCookie As HttpCookie = New HttpCookie("ASP.NET_SessionId")
MyCookie.Expires = System.DateTime.Now.AddDays(-1)
Response.Cookies.Add(MyCookie)
'C# code
'HttpCookie mycookie = new HttpCookie("ASP.NET_SessionId");
'mycookie.Expires = DateTime.Now.AddDays(-1);
'Response.Cookies.Add(mycookie);
Response.Redirect("/timeout.aspx")
End If
End If
End Sub
Are you calling Session.Abandon in your special "Your session expired" page? If so, don't.

Resources