I have a web application using cookieless forms authentication. Every day my event log has a ton of 4005 error codes (Forms authentication failed for the request). I believe this is happening because users are bookmarking pages while they are logged in so when they revisit the forms ticket in the url has expired, atleast this is the only scenario I can trigger in testing.
My question is it possible to disable logging for this 4005 code ? its filling up my event log
You can handle the error so it does not appear in the log
'in global.asax
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs when an unhandled error occurs
Dim lastError As Exception = Server.GetLastError()
' Must be a better way, just can remember how, you will get the idea.
If lastError.Message.Contains("Forms authentication failed for the request") Then
'do nothing
Server.ClearError()
End If
End Sub
If you can use cookies, its a much better solution than cookieless mode because your users will get to use bookmarks, which they'd surely expect to be able to do, and your error log will not be filled with errors. Its also less vulnerable to session hijacking.
Not an answer to your question, and I'm not even familiar with ASP. But if, just like for example PHPSESSID and jsessionid, this "forms ticket in the url" is actually a session id that is also added to the URL for anonymous visitors, then maybe search engines can cause this error as well? And if so: doesn't that break your search scores?
Related
Well, I have 2 ASP.NET WebForm websites, running on production on the same windows server machine, let's call them site A and site B. There are some pages in website A in which there is an iFrame, pointing to website B. I want my users to be authenticated on site B when they browse site B through site A (through iFrames). In order to do that, the source of my iFrame on my site A is like that :
B.com/index.aspx?guid={aGuid}&pageIWant={pageIWant}
So, I will not go into details there because it works and it is not the problem, but how it works basically is that in the Page_Load of index.aspx.vb of my site B, I get the guid in the querystrings representing a user, I get this user from database, I log this user using forms authentication and then I redirect the user to the "pageIWant", another querystrings parameter. So, here is what I do in the page_load, basically :
/*Get the guid*/
Dim user = /*get user from guid*/
/*some checks*/
FormsAuthentication.SetAuthCookie(user.Login, True)
Select Case Request.QueryString("pageIWant")
Case "1"
Response.Redirect("documents.aspx")
Case "2"
/*etc*/
End Select
The index.aspx page of site B does not require authentication, but the page "documents.aspx" does. Hopefully, I did authenticate my user in the page load of index.aspx, so I go through Application_AuthenticateRequest in the Global.asax.vb and everything is fine, my user can access the page. Here is the code in my Application_AuthenticateRequest method :
Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
If Request.IsAuthenticated Then
If Request.Cookies("ESERVICES_LOGIN") IsNot Nothing Then
Dim aTicket As FormsAuthenticationTicket = FormsAuthentication.Decrypt(Request.Cookies("ESERVICES_LOGIN").Value)
HttpContext.Current.User = New GenericPrincipal(New GenericIdentity(aTicket.Name), aTicket.UserData.Split(","c))
Else
FormsAuthentication.SignOut()
HttpContext.Current.User = New GenericPrincipal(New GenericIdentity(String.Empty, String.Empty), New String() {})
Response.Clear()
End If
End If
End Sub
In this case, when I redirect to the page "documents.aspx", the Request.IsAuthenticated is set to true because I previously called FormsAuthentication.SetAuthCookie(user.Login, True)
Here is the problem : since I installed on my windows server machine (hosting the websites) the two following KBs :
https://support.microsoft.com/en-us/help/4534978/kb4534978
https://support.microsoft.com/en-us/help/4535104/kb4535104
Request.IsAuthenticated is still false when I redirect to "documents.aspx" page, despite the fact that I call FormsAuthentication.SetAuthCookie before... and no exception is thrown ! My user is not logged in anymore.
I uninstalled the two KB and the problem is not occuring anymore, so I am sure there is something with one of those two KBs that causes my problem.
Something really strange is that when I try to reproduce the problem in localhost, I do not face the problem at all -> the problem seems to happen only when website A and website B do not have the same domain name. I've made multiple tests about this hypothesis and it seems to be true.
So, there is something wrong with the framework (or how I use it), and because of that, FormsAuthentication does not work properly through iFrame, when the iFrame source does not have the same domain name as the iFrame container, and when those two KBs are installed on the windows server machine hosting the website. That is silly and I cannot find the problem when debugging.
Please note that in both case, wheter authentication works or not, my auth cookie is created successfully...
Would someone have any idea about what's happening there? Do not hesitate to ask any questions if my problem is not clear.
Regards
I found an explanation.
Since 2019, Microsoft is releasing KBs that changes the default value of the "SameSite" attribute for the cookies. Before, when creating an auth cookie with FormsAuthentication.SetAuthCookie, the SameSite attribute was not specified, and in most browsers, the default value for it was "none" and it worked just fine. (this is not the case with Chrome anymore since february 2020, the default value became "lax").
Now, with the KBs I mentionned, the default value became "Strict", that's why my authentication doesn't work anymore in my case.
So, I'll have to specify the samesite attribute of my auth cookie to "None" manually if possible, and think about the security issues I could have with that. As a last resort, I could also just use the same domain name for my two websites.
Ok so far i have working the ability to log in and access a certain web page ('bookrepair.aspx') through the use of roles and permissions. I used this to then deny any non-logged on users which works however it throws me up the "Server in '/' Application error". However i would like it to redirect the user to the home page ('home.aspx') and display a message to them saying "Only logged in users can access Book Repair"
So for i have this piece of code in my 'bookrepair.aspx' page
Private Sub Pages_BookRepair_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Me.Page.User.Identity.IsAuthenticated Then
Response.Redirect("Home.aspx")
MsgBox("Only logged in user's can access Book Repair")
End If
End Sub
However i still get the "Server in '/' Application error when trying to access it not logged in.
Any ideas?
I don't use the User.Identity functionality just because of all the issues you have to address in order to authenticate users. I make it simple and set a flag in either the Session or ViewState object which would indicated whether or not the user is logged on. For example:
If Session("LoggedOn") = "NO" Then
Response.Redirest("MainPage.aspx", False) 'False to indicate that the rest of the code in the procedure is not to be executed.
End IF
It's what works best for me, I have total control over it, do not have to worry that the browser supports it because Session is maintained on the server. I've never had an issue with it.
In my Global.asax file I have a Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs) which "should" capture all errors experienced by the application (correct me if I'm wrong here).
My question is, I've seen errors recorded which apparently did not "fail" in terms of my users seeing the custom error page. So what would tell me, if anything, whether or not the type of exception actually caused the custom error page to show.
I want to get better at error handling and looking for any insight or ways to improve the user's experience. Thanks!
In two words:
Handle all your errors at the page, and show to the user a message for what is do wrong.
Keep the global error handler for unknown to you errors, for log them and fix them in the near future, and show a general error page to your user.
For more informations and details I have write this answer: How do I make a "generic error" page in my ASP.NET application so that it handles errors triggered when serving that page itself?
Essentially I want to be able to catch when a user lets their session timeout and then clicks on something that ends up causing an Async postback. I figured out that if I put this code in my Session_Start (in Global.asax) then I can catch a postback that occurred during a session timeout:
With HttpContext.Current
If TypeOf .Handler Is Page Then
Dim page As Page = CType(.Handler, Page)
If page IsNot Nothing AndAlso page.IsPostBack Then
'Session timeout
End If
End If
End With
This works fine. My question is, I would like to be able to inject some javascript into the Response and then call Response.End() so that the rest of the application does not get finish executing. The problem is that when I try Response.Write("<script ... ") followed by Response.End() then javascript does not get written to the response stream. I'm sure there are other places in the application that I can safely write Javascript to the Response but I can't let the rest of the application execute because it will error when it tries to access the session objects.
To sum up: I need to inject javascript into the response in the Session_Start event in Global.asax
Note: You may be wondering why I'm not doing this in Session_End...we don't use InProc sessions and so Session_End doesn't get called...but that's beside the point...just wanted to make it clear why I'm doing this in Session_Start.
Writing to the response stream outside of an HttpHandler is generally not a good idea; it may work in some corner cases, but it's not how things are intended to work.
Have you considered using either a Page base class or a Page Adapter to do this? That way, you would only need one copy of the code, and it could be applied to either all pages or just the ones you select.
Another option would be to use URL rewriting to redirect the incoming request to a page that generates the script output you need.
My goal is to write a cookie when the user authenticates. We are using a crappy framework that hides its source code and event model so when I use their login control I can't set a session timeout on it!
Anyhow, I am trying to write a cookie when the user is logged in, and then refresh the cookie expire time on subsequent page views (sliding expiration).
So I figured I could initially create the cookie during Application_AuthenticateRequest in teh global.asax but that seems to be firing even when the user hasn't signed in yet.
Is that suppose to be the case?
The Application_AuthenticateRequest fires on each request, but if you are using forms authentication and the user haven't logged in yet, you will find that the User property of the HttpContext (accessed through this.User in the global application class file) evaluates to null, while it will evaluate to an IPrincipal object if the user is logged in.
So you can do something like this:
Private Sub Application_AuthenticateRequest(ByVal pObjSender As Object, ByVal pEaDummy As EventArgs)
If Me.User IsNot Nothing AndAlso Me.User.Identity.IsAuthenticated Then
If Me.Request.Cookies("authCookieName") Is Nothing Then
' Create cookie
Else
' Update cookie
End If
End If
End Sub
where authCookieName is the cookie name.
Yes. The Application_AuthenticateRequest will occur everytime a request hits the website. The AuthenticateRequest as well as doing the authentication will also check and return if Authorisation is to happen for the page. Some pages need to be excluded from authentication and authorisation checks, such as the login page.
For your situation you should also check the page and exclude those that are involved in the login sequence.