This is the situation:
I use a third-party library to do some SPF checks
The checks are done from an ASP.NET web site
The third-party library uses lots of 'await/async' code, although I am calling a non-async method to do it
Most of the time, w3wp (yes, the actual w3wp.exe) simply crashes with the following error ' Invalid token for impersonation - it cannot be duplicated'.
I am assuming this is because the await/async grabbed a Thread from the threadpool which has some sort of illegal / weird identity on it, so I am wondering if there's any way to call a bit of code and tell .Net to 'forget about' async/await and just run it synchronously, on the same thread.
I've found a solution: somewhere in the product the user was being impersonated with identity.impersonate(), but the impersonation context was never .undo()'d. After making sure the identity.impersonate() was properly matched by an .undo(), the problem stopped occurring.
I did try making my own SynchronizationContext, but that didn't work in this instance, as passing on the impersonation just passed on the 'illegal' impersonation context too.
I'm new to this AJAX approach when you're not supposed to use UpdatePanel but rather go with WebMethods and WebServices. My main problem is authentication.
When page is entered or postback request is created, everything works fine. Authentication is passed correctly and I can access Thread.CurrentPrincipal.Identity and get my user identity object from there.
However this changes when I try to call WebMethod on my page. Call is passed correctly to server and everything seems to work just fine until i try to get user identity from thread. Then I get just Anonymous user instead of real one. Enabling session on webmethod didn't seem to help much.
Any ideas what might cause this problem and how to solve it? Someone mentioned that authentication cookie needs to be passed along with the request, but how am I supposed to do it?
Any help will be appreciated.
Edit:
Some clarification and code:
My application is written in standard asp.net. After some deeper research in legacy code I've found out, that all authentications are done in some base class from wchich all other pages inherit. Each time page is loaded, user principal are obtained from HttpContext.Current.Session("..."). I think this is far from good solution, but I'll need to stick with it right now. Problem was, WebMethod is not firing whole page lifecycle since it's static. I've fixed it right now by calling method that obtains user data from session.
I would like to get some ideas how this could be created correctly and what problems might be result of session based authentication.
PageMethods.SomeMethod(parameter, SuccessDelegate, FailureDelegate);
This is how I'm calling WebMethods right now. I assume it's passing all required cookies, am I right?
It depends on how you're calling the method and in what manner?
Jquery for instance with its Post method should push all cookies (including your FormsAuth / Session cookie) up with the request that should still authenticate as appropriate. Bare metal techniques might be making lightweight calls that simply do not push the cookie up...One way to monitor this is by using Fiddler to observe the request and a browser based development plugin like Firebug and see what is occuring and amend your JS code as appropriate.
Personally, if you are starting a brand new project and there is no pressing need to expose your services beyond your web application then I would suggest looking at ASP.NET MVC where you can make Jquery / client-side up to the controller and get your authentication wrapped up for free. I've recently created something simliar using WCF JSON endpoints and some inevitable pain, I then saw MVC and kinda kicked myself...
As noted in comment above, the issue lies in legacy code that handles users. It is needed to make call to special function that assigns appropriate user data to handling thread. Not a best solution, but that's how it sometimes is with legacy code. What you gonna do?
I have a Relying Party and a provider running with DotNetOpenAuth. The issue is that when the provider has not been accessed in a while it is unloaded from IIS to conserve memory (which is normally a good thing). However, in this case it causes the Relying Party to throw the "No OpenID endpoint found" exception.
I know that IIS can be configured to never unload an application, but that is not an option in this case.
Is there a way to increase the timeout on the relying party to let it wait until the provider "wakes up" and not throw the No OpenId Endpoint Found exception?.
I thought I had it with the "maxAuthenticationTime" property, but I guess this is really a setting for how many minutes in total the authentication round trip should be allowed to take.
Thanks.
Yes, these timeouts can be configured via your web.config file. Below is a snippet, with the defaults which you can raise:
<messaging>
<untrustedWebRequest
timeout="00:00:10"
readWriteTimeout="00:00:01.500"
Full configuration options are documented.
I'm using ASP.NET and rely on the web.config file to secure sections of my site. However, is this truly reliable, or is it also a good idea to add an IsAuthenticated check in the Page_Load event? Also, is it possible for someone to directly call methods (assuming they somehow got my method names and method signature) in my application's DLL? For example, I have a method to add users to a specific group. Can an attacker somehow call that method through their own custom POST and execute it?
Thanks
If you are concerned about specific methods being executed without permission, I'd use code attribute security or your own roles check system to secure the method regardless of who's calling it. I could imagine scenarios where even friendly developers call methods accidentally without making sure the code path has the right to perform privileged functions.
I'm looking for the best way to log errors in an ASP.NET application.
I want to be able to receive emails when errors occurs in my application, with detailed information about the Exception and the current Request.
In my company we used to have our own ErrorMailer, catching everything in the Global.asax Application_Error. It was "Ok" but not very flexible nor configurable.
We switched recently to NLog. It's much more configurable, we can define different targets for the errors, filter them, buffer them (not tried yet). It's a very good improvement.
But I discovered lately that there's a whole Namespace in the .Net framework for this purpose : System.Web.Management and it can be configured in the healthMonitoring section of web.config.
Have you ever worked with .Net health monitoring? What is your solution for error logging?
I use elmah. It has some really nice features and here is a CodeProject article on it. I think the StackOverflow team uses elmah also!
I've been using Log4net, configured to email details of fatal errors. It's also set up to log everything to a log file, which is invaluable when trying to debug problems. The other benefit is that if that standard functionality doesn't do what you want it to, it's fairly easy to write a custom appender which can process the logging information as required.
Having said that, I'm using this in tandem with a custom error handler which sends out a html email with a bit more information than is included in the standard log4net emails - page, session variables, cookies, http server variables, etc.
These are both wired up in the Application_OnError event, where the exception is logged as a fatal exception in log4net (which then causes it to be emailed to a specified email address), and also handled using the custom error handler.
First heard about Elmah from the Coding Horror blog entry, Crash Responsibly, and although it looks promising I'm yet to implement it any projects.
I've been using the Enterprise Library's Logging objects. It allows you to have different types of logging (flat file, e-mail, and/or database). It's pretty customizable and has a pretty good interface for updating your web.config for the configuration of the logging. Usually I call my logging from the On Error in the Global.asax.
Here's a link to the MSDN
I use log4net and where ever I expect an exception I log it to the appropriate level. I tend not to re-throw the exception because it doesn't really allow for as-nice user experience, there is less info you can provide at the current state.
I'll have Application_Error also configured to catch any exception which was not expected and the error is logged as a Fatal priority through log4net (well, 404's are detected and logged as Info as they aren't that high severity).
My team uses log4net from Apache. It's pretty lightweight and easy to setup. Best of all, it's completely configurable from the web.config file, so once you've got the hooks in your code setup, you can completely change the way logging is done just by changing the web.config file.
log4net supports logging to a wide variety of locations - database, email, text file, Windows event log, etc. My team has it configured to send detailed error information to a database, and also send an email to the entire team with enough information for us to determine in which part of the code the error originated. Then we know who is responsible for that piece of code, and they can go to the database to get more detailed information.
I recently built an asp.net webservice with NLog, which I use for all my desktop apps. The logging works fine when I'm debugging in Visual Studio, but as soon as I switch to IIS the log file isn't created; I've not yet determined why, but it the fact that I need to look for a solution makes me want to try something else for my asp.net needs!
We use EnterpriseLibrary.ExceptionHandling.Logging. I like it a bit better than log4net because not only do we control the logging completely, but we can control the Throw/NoThrow decision within config as well.
We use a custom homegrown logging util we wrote. It requires you to implement logging on your own everywhere you need it. But, it also allows you to capture a lot more than just the exception.
For example our code would look like this:
Try
Dim p as New Person()
p.Name = "Joe"
p.Age = 30
Catch ex as Exception
Log.LogException(ex,"Err creating person and assigning name/age")
Throw ex
End Try
This way our logger will write all the info we need to a SQL database. We have email alerts set up at the DB level to look for certain errors or frequently occurring errors. It helps us identify exactly where the errors are coming from.
This might not be exactly what you're looking for. Another approach similar to using Global.asax is to us a code injection technique like AOP with PostSharp. This allows you to inject custom code at the beginning and end of every method or on every exception. It's an interesting approach but I believe it may have a heavy performance overhead.