We have two server running .NET 4.5.1 and one running .NET 4.0. Before updating the first two, our SSO for forms authentication worked fine. Now, a user will appear authenticated on those first two servers, but not authenticated on the .NET 4.0 box.
All machine keys, decryption keys, cookie domains, etc, are all the same. No code was modified. We simply applied the 4.5.1 update to those two servers.
I've noticed for the 4.0 server, while our authentication cookie IS being passed up, it's not being recognized by the code (I threw a test page on the site and outputted some variables).
Has machine key encryption changed between 4.0 and 4.5.1? Do I need to apply some patch? Thanks.
The encryption APIs have changed in 4.5 see this blog post for more detail - http://blogs.msdn.com/b/webdev/archive/2012/10/23/cryptographic-improvements-in-asp-net-4-5-pt-2.aspx
According to MS simply upgrading to 4.5 wouldn't affect the apps unless the web.configs have changed to target 4.5 which seems odd in your case. You can try adding this attribute to each web.config to force .NET 2.0 compatibility-
<machineKey compatibilityMode="Framework20SP1" />
Related
We have a legacy web api project developed years ago, it is supposed to be consumed by other internal projects (so not something to be exposed by users over Internet).
The prject was developed in .net 4.6.1 and I am looking at moving it to .net 6. By reading the code and web.config, I got confused with these:
Is it acceptable or best practice to keep on using web.config in .net 6 for these settings or it is better to do in other places? (seems I can't type web.config in stackoverflow and have to make a screenshot)
In our web.config, we have this: <httpCookies httpOnlyCookies="true" requireSSL="true" />
For this web api, we just send some response back and I can't think a place that we use cookie. For authentication, as this web api is consumed by other internal products, we just authenticate the bear token each request sent with the identity server. So is this line really needed? I can't find an equivalent line in .net 6's web.config
There are different ways on specifying application settings in .NET 6, depending on what kind of setting it is and how you want to structure your project. As Marc says the most common application configuration file for .NET Core is that I have seen is: appSettings.json.
You might want to configure some settings directly in your Program.cs and other settings (especially settings that need to be transformed between environments) could be in a transformable settings file like appSettings.json or lauchSettings.json. Read more about configuration in .NET 6 here.
To conclude I would say that it is not best practice to keep the web.config but rather to extract the configuration to the place you see fit. If you don't host you app on a server that needs web.config to run then remove it.
This is a bit harder to answer. If you don't think you need this setting then you can try to omit it when you migrate your application to .NET 6. If you have multiple environments you should test your application (the .NET 6 version) in a non production environment and then you will get your answer if you need to configure that setting or not in the migrated application.
I wish you good luck in your migration journey! :)
I have a web application that usually runs with a .NET 2.0 AppPool account. But because the AJAX calls posts string serialized XML to the server, I needed to add the "requestValidationMode" option to the httpRuntime setting when running the same AppPool account with .NET 4.0.
However, switching back to .NET 2.0, the application responds with error with regards to the "requestValidationMode" option.
Is there a way one can have one web.config with some conditional mark-up so one need not edit the web.config each time the version of .NET is changed for the AppPool?
Any help would be greatly appreciated.
I have an ASP.NET system with a structure like this, hosting both .Net 1.1 and .Net 2.0 apps on the same server:
/apps11/app1
/apps11/app2
/apps11/web.config
/apps20/app3
/apps20/app4
/apps20/web.config
These above two web.config files have sections specific to their version of .Net, but the parts that relate to forms authentication and machine key were identical (so that the forms authentication cookie could be shared between apps on different versions). The section is shown below (with real key obfuscated but exact length and settings preserved):
<machineKey
validationKey="AAAABBBBCCCCDDDDEEEEFFFF0000111122223333"
decryptionKey="BBBB9999AAAA1111"
validation="SHA1">
</machineKey>
<authentication mode="Forms">
<forms name=".ASPXAUTH" protection="All" timeout="15" path="/" loginUrl="/apps20/login.aspx"></forms>
</authentication>
After an upgrade of the login page component of the app, the shared authentication stopped working for the 1.1 apps. I could log in to the 2.0 apps but when I navigated to a 1.1 app it would continually redirect me back to the login page. Went through the following troubleshooting steps:
An issue with MS10-070 and needing the KB243375 patch? It had already been applied on the server.
Machinekey broken by the installer? I checked the machinekey values and the installer had updated the validationKey and encryptionKey values. However, the settings remained the same (validation="SHA1") and the same machinekey was in both web.config files.
Some other value in machine.config or web.config for each .Net Framework version? Found a domain setting in the .Net 2.0 web.config, but that seemed to only impact the domain of the ticket cookie, not the content of it.
Problem with encryption settings between 1.1 and 2.0 as described in How To Share Authentication Cookies across ASP.NET V1.1 and ASP.NET V2.0 Applications? Nothing had changed except the key values, so why would it break now?
Answering my own question. This many years after .Net 1.1, I doubt many other people will need this info, but putting it out here just in case...
In the end, the problem was indeed #4 above. Not only the keys had changed, but also the length of the keys:
<machineKey
validationKey="EEEEEEEE77778888999900001111AAAABBBBCCCCDDDDFFFFAAAABBBBCCCCDDDDEEEEFFFF1111222233334444555566667777888899990000AAAABBBBCCCCDDDD"
decryptionKey="888899990000111122223333444455556666777788889999" validation="SHA1">
</machineKey>
The clue came in this Security via in ASP.NET 2.0 article, which says "The decryption attribute is a new addition in ASP.NET 2.0 to reduce the overloading of the older version of the validation attribute. The Auto option for this attribute uses an algorithm that is inferred from the key size. Triple DES encryption is the default, but a key of 128 or 256 bits will use AES."
Adding encryption="3DES" to my machineKey tag in the .Net 2.0 web.config solved the issue. It worked for years because the old key was short enough that it inferred 3DES. The new key was long enough that it inferred AES.
I went back and read the MSDN documentation for the machineKey element. It simply says "ASP.NET determines which decryption algorithm to use, based on configuration settings". And while later in the topic it tells you what length of key to use for each encryption type, it doesn't say that the encryption type is inferred from the length. In fact, it tells you how to use a shorter key than the recommended length (not sure why you'd want to).
Any better solutions to this? Am I the only one who thinks the MSDN doc is somewhat lacking on this point?
Let me describe my setup a little before I get into the problem. I have two web servers (www.mydomain.com and www2.mydomain.com) using Forms Authentication. On each web server I have a main application for authentication and numerous sub-apps. It looks kind of like this:
www.mydomain.com
|__MainApp (.Net 2.0)
|__SubApp1 (.Net 1.1)
|__SubApp2 (.Net 2.0)
|__SubApp3 (.Net 2.0)
www2.mydomain.com
|__MainApp (.Net 2.0)
|__SubApp1 (.Net 1.1)
|__SubApp2 (.Net 2.0)
|__SubApp3 (.Net 2.0)
As you can see, I'm running a mix of .Net 1.1 and 2.0 applications on the same server. Now I've been trying to come up with a Single Sign- On (SSO) solution that works with this setup and I've partially succeeded. Because the domain attribute in the tag is incompatible with .Net 1.1 (it causes the apps to throw an exception), I decided to programmatically set the domain of the forms authentication cookie generated. This works fine and I can navigate between the two servers without having to login again. The problem occurs when the server tries to reissue/renew the cookie and update its expiration with slidingExpiration enabled. The cookie I generate gets created with "mydomain.com" as the domain, but when the server tries to reissue it with a new expiration, it can't find it and generates a brand new cookie with "www.mydomain.com" as the domain.
Is there anyway to have the server properly reissue the original cookie with the custom domain?
We have an almost identical setup (two web servers, a mix of 1.1, 2.0 and 3.5 app's) and SSO using forms authentication. And we've got it working with sliding expiration with no problem.
The one difference is that our two web servers are setup as a web farm (using the MS Clustering in Server 2k3 if I remember correctly). This means that both machines are assigned to the same domain. Can you switch your two servers to be a web farm?
If we were to go that route, it would be more of a long-term solution. In the short term, I was just hoping to see if anyone knew why the framework is unable to find and reissue the existing cookie.
My solution was to add the Forms Authentication domain attribute to the global Web.config for the .Net 2.0 framework (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\Web.config). It doesn't fix the issue for my .Net 1.1 apps, but the majority of my apps are on 2.0. I'll probably just use an HTTPModule to handle the sliding expiration for the .Net 1.1 apps.
we're in the process of migrating our web app from ASP.NET 1.1 to ASP.NET 3.5. Our app runs on multiple servers through DNS round robin, so every browser request may end up on a different server. We do have a in our web.config to prevent validation errors.
However, our plan was to migrate one server at a time. Now it looks like when a user loads the page on a 1.1. server and then the page ends up on a 3.5 server on postback, the viewstate validation fails.
I haven't been able to find anything on the web regarding this issue - it's just my guess that the viewstate validation is incompatible between 1.1. and 3.5, i.e. a viewstate generated by 1.1 will not validate on 3.5 even with the same machineKey and vice versa.
Can anyone confirm this suspicion?
Thanks
Use sticky sessions as mentioned in this similar post. This will keep users on the same machine for a period of time.
I don't think it wise to allow a single user to hit three different versions of the framework in a single session.
Are you running IIS7 for the 3.5 host? I ran into a lot of issues with ViewState running a 1.1 app on IIS7. Getting a 1.1 app running properly on IIS7 is diffucult enough, let alone trying to web-garden across multiple framework versions. The biggest thing I ran into is that ViewState is encrypted or managed differently than previos version of IIS. If you try to setup a weg-garden on a 1.1 you get all kinds of ViewState encryption errors. You cannot setup a web garden (have multiple worker threads) on a 1.1 app on IIS7. At least from my experience.
I believe 1.1 and 2.0 use different default encryption algorithms for the viewstate. The default for 1.1 was 3DES and I believe for 2.0 it was SHA1 (Although I can't seem to find the documentation to back this up at the moment). Try setting the validation in your machine key to 3DES on the new server and see if that solves the problem.
<machineKey validation="3DES">