Form authentication problem with multiple IIS worker processes - asp.net-mvc

I'm running an asp.net mvc5 application on a shared hosting environment (a2 Hosting). I ran into a problem where users get randomly un-authenticated when browsing pages WAY before session timout or expiration should be reached.
I tried playing with applicaiton pool configurations to fixed the problem and finally find out that this was related to numbers of worker processes. When the maximum number of worker processes is set to 1, no more disconnection problems.
My appliciation use real basic from authentication. The only customizing I did was usins a custom Principal object to store extra data in authentication cookie. I DON'T use Session in the application so this can't be the problem.

Set it back to 1. Why you shouldn't use web gardens: https://www.youtube.com/watch?v=9bOTesCnszo

For enabling multiple IIS worker processes.
Go to Services & find Asp.Net State Service Set it to Startup
Automatic
Open IIS Manager Goto Web Application, right click and select Explore, this will take you to the folder, find web.config file & edit this file in notepad and Change Session State to State server and Save the web.config file.
Now edit the app pool by right clicking on it & select Advanced settings and find Maximum Worker processes & change the value & change load user profile to true. Click on OK. Open command prompt as Admin and run an "IISRESET" after complete, TEST.
This helps to boost overall application performance.

Related

Users are logged out randomly from the application (after implemented 2FA)

I have a strange situation in the live environment and it is imposible to figure out what is the issue.
The users complain about the fact they are logged out after a random time.
On the client side it is an ASP MVC application that runs in IIS. Regarding the server side, it is and .net WebApi application that also runs in IIS. This is the session settings from web.config file of the client app:
<sessionState cookieless="false" mode="InProc" timeout="120" />
Even if I have set 120 minutes in config or in IIS advanced settings, they got the logout.
I have a recycle process set at 01:00 in the middle of the night. I have checked the logs files from EvenViewer and there are no other recycle processes trigered, only that one from the middle of the night.
The idea is that I can't reproduce it on my local machine. It happens at any time during the 120 minutes that are configured.
Few weeks ago, I have implemented a mechanism for 2FA using the following library: https://github.com/RobThree/TwoFactorAuth.Net and a functionality "Trust this browser for the next 30 days" in order to skip the MFA authentication if the user want this. Actually, I just keep and expiration date in a cookie in order to know when should I reset the option and ask again the user for a new authentication code. Don't know if it is related to this, but they told me that they encountered this situation after I released that 2FA implementation.
UPDATE After I read more articles in order so solve this issue, I want to add that the aplication is hosted in AZURE. Maybe this information helps.
UPDATE Advanced settings from IIS
UPDATE This are session state settings
Any suggestions would help. Thanks in advance.

Asp.Net MVC authencation with Wep Api

I am developing an MVC project with the web API. When the user logs in, I am sending a token to the web service. I keep this token in the Session object on the MVC side. If this session is null, I want to log in again from the user. But sometimes this session object is deleted by itself. What could be the reason for this?
Session has a timeout period of 20 minutes. It could mean that your user did not post anything back to the server within these 20 minutes.
Another problem that might cause a session timeout is if you change something in web.config or some other file through Visual Studio for example. This will trigger the compilation process in the background and will reset your session.
The default session, out of the box one, is InProc session. This means that your session is running in the same process as your web application.
If you want to preserve the session while still being able to update the web application, you need to use either Out of process or SQL Server as a session store. (Note that these session states are not really meant for the scenario where you will be updating things locally, but rather when in production and/or if you have a web farm, but nothing prevents you from using them locally.)
StateServer (out of process)
This session mode will use a service call ASP.NET State Service. This service is set to manual. You will first need to open services (click on Start -> Run -> services.msc). Find the above mentioned service, double click and change the startup to Automatic, then Start.
In your web.config you will need to update or add (if it does not exist) the following key under <system.web>:
<sessionState mode="StateServer"
stateConnectionString="tcpip=YourComputerNameGoesHere:42424"
cookieless="false"
timeout="20"/>
Update the timeout value to whatever it suits you.
SQLServer state
SQL Server state allows you to store your sessions in a designated database on your server. One thing you must remember is that this is the slowest option of all as it has to travel from server to server (in your case it might be the same server, but keep this in mind if you separate web application and sql server)
To configure SQLServer state you must perform a couple of extra steps. First, add the configuration to the web.config:
<sessionState mode="SQLServer"
sqlConnectionString="Integrated Security=SSPI;data source=MySqlServerForSessions;" />
(I cannot recall now whether you can change the name of the database, but for now work with the default values.)
The next step is to run aspnet_regsql command from your command prompt. This command should be in your C:\Windows\Microsoft.NET\Framework\vX.Y.ZZZZ (where X.Y.ZZZZ is the version of .NET Framework. Try with the highest one that you have):
aspnet_regsql.exe -S MySqlServerForSessions -E -ssadd -sstype p
This will create a new database where the sessions will be stored. If you have SQLExpress you might run into an issue when running this command. For that you need to run:
EXECUTE sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
GO
EXECUTE sp_configure 'Agent XPs', 1
RECONFIGURE WITH OVERRIDE
GO
EXECUTE sp_configure 'show advanced options', 0
RECONFIGURE WITH OVERRIDE
GO
This should help you work with the sessions. One thing to remember is that in global.asax you cannot use Session_End event when you use StateServer or SQLServer. This event triggers only for InProc session state.
For more information have a look at these two links:
ASP.NET Session State Overview
Session-State Modes
Handling Session and Authentication Timeouts in ASP.NET MVC

losing session data in asp.net

My IIS session occasionally loses all data stored in it, it usually takes about 3-5 minutes, but definately less then the session timeout set in the web.config. The problem is not reproducible reliably, when it happens, accoring to the logs the AppPool is not recycled and the Session ID remains the same, it just loses all data. Any suggestions on how to debug this?
So far I tried to overwrite the session provider and stored the session data into a static variable, we checked all relevant timeouts and we stored a dummy value in the session, that is lost as well
A number of things can cause session state to mysteriously disappear.
Your sessionState timeout has expired
You update your web.config or other file type that causes your AppDomain to recycle
Your AppPool in IIS recycles
You update your site with a lot of files, and ASP.NET proactively destroys your AppDomain to recompile and preserve memory.
If you are using IIS 7 or 7.5, here are a few things to look for:
By default, IIS sets AppPools to turn themselves off after a period of inactivity.
By default, IIS sets AppPools to recycle every 1740 minutes (obviously depending on your root configuration, but that's the default)
In IIS, check out the "Advanced Settings" of your AppPool. In there is a property called "Idle Time-out". Set that to zero or to a higher number than the default (20).
In IIS, check the "Recycling" settings of your AppPool. Here you can enable or disable your AppPool from recycling. The 2nd page of the wizard is a way to log to the Event Log each type of AppPool shut down.
If you are using IIS 6, the same settings apply (for the most part but with different ways of getting to them), however getting them to log the recycles is more of a pain. Here is a link to a way to get IIS 6 to log AppPool recycle events:

Clever way to put azure MVC app into maintenance mode

Does anybody have any quick and clever ways to flip an MVC app running on Windows Azure into a "maintenace mode"
I don't have a huge need for this because I use the azure staging environment a lot but occasionally I do have the need to make sure there are no users in the production instance of the application (mainly database updates).
I'd like to be able to do this on the fly without uploading new code or swapping deployment slots. Any suggestions?
The friendliest way to do it is on login. When a user authenticates, check a maintenance mode flag in the database and don't let them log in. Let active users continue to use the application until they log out or their session times out. Keep an activity log so you can know when all users have expired.
Of course this means it will take time from when you put the app into maintenance mode and when it is effectively ready, but it's not nice to boot out an active user.
If the usage pattern of your app makes it so this methodology will not ensure no activity in a reasonable time, you can add a timeout on top of this. Check the same maintenance flag for a request every so often. Doesn't have to be every request but every five minutes or so. If necessary you can also cache the maintenance mode value locally for a reasonable period of time (a few minutes).
I would use routing for this. Have the flag be inspected during routing configuration. If it is on, route to "Maintenance" screens
I would suggest adding a Global Action Filter that respects you maintenance mode Flag.

IIS7, SQL 2008 and ASP.NET MVC security

I have an ASP.NET MVC application that I'm working on. I've been developing it on Windows Server 2003 with IIS6 and SQL 2008 Express, and everything was working great. I recently decided to try out the Windows 7 beta, so now I'm using IIS7, and have run into a problem with connectivity to my database that I can't seem to figure out.
I can run/debug the app just fine, but whenever I try to access a page that needs to access the database, I get the following error:
"Cannot open database "MyDatabaseName" requested by the login. The login failed.
Login failed for user 'IIS APPPOOL\MyApplicationName'."
I've obviously got some security configuration setup incorrectly, but I can't seem to find any good documentation on how to set it up correctly. I've tried giving NETWORK SERVICE permissions on the database, but that didn't seem to work. Anyone know what I need to do to give "IIS APPPOOL\MyApplicationName" permissions to this database? Am I missing something obvious?
Thanks...
If you are NOT using Active Directory, then ignore all of the other solutions mentioned here. The confusion stems from the new ApplicationPoolIdentity setting default in IIS 7.5+ (MS keeps changing the identity mechianisms)
Open SQL Management Studio, connect to your local machine as an admin.
Expand the Security branch.
Right click on Logins and select New Login
Into the Login Name field, type "IIS APPPOOL\MyApplicationName". Do NOT click the search button. The user profile dosn't actually exist on the local machine, it's dynamically created on demand.
While you're looking at it, don't forget to add the user to a database or a server role.
The error means the web application doesn't have access to your database. On Windows 7 / IIS 7, by default each application pool has its own user. It seems the idea is to improve security by restricting what that web application can do (in case it gets compromised and controlled from the outside). You can change what user the application pool is running under but that will defeat its own purpose. A better way seems to give the pool's user the needed permissions (and not a bit more).
On the SQL Management Studio connect to the server you want your web app to connect (tested with SQL server 2008). Go to
Security -> Log ins
right click, New Log in. In the form that comes up leave everything as default except username, where you have to type whatever username the web app is trying to use, in this case 'IIS APPPOOL\MyApplicationName'. Note that the search function of that dialog fails to find or check as valid that user, but nevertheless it works.
Still on the SQL Management Studio connected to the server go to
Databases -> *YOUR-DATABASE* -> Security -> Users
right click and New User. I'm not sure if the user name field there has any effect, I just set it the last part of the username, like MyApplicationName. Then I've set the login name to IIS APPPOOL\MyApplicationName. You can click on the ... button and use the check and search, this time it works. If you don't do the previous step, the user will not be present here. Then give it whatever permissions you want to this user, like db_datareader.
And that's it, you've given permission. If lack of permissions was your problem, then it should be solved (or at least, I've just solved it that way).
I have a total amount of 2hs of experience with IIS and about three weeks with SQL Server and less than two months with Microsoft technologies so take my advice with a grain of salt, I can be totally wrong. (If another person can confirm these are the right steps, feel free to remove the last warning).
Here is an article that explains why AppPoolIdentities are in use; basically, it's about enhanced security: http://learn.iis.net/page.aspx/624/application-pool-identities/
(That article claims I can use these virtual accounts just like any regular account but on my Windows Server 2008 that does not seem to be possible; adding e.g. IIS AppPool\DefaultAppPool just produces an error: "The following object is not from a domain listed in the Select Location dialog box, and is therefore not valid.")
Erick Falsken is right, however he is missing the User Mappings. So right click on the new
IIS APPPOOL/DefaultAppPool, click on Properties and then check boxes for:
1) databases master and yourdatabase
2) db_owner and public
This error usually means that the user that your site is running as (or more to the point the application pool), does not have permissions to use the DB. You can either check in IIS what user the pool is running under and give them permissions, or instead change your SQL connection string to not use trusted authentication and supply the credentials of a user that does have permission in the connection string.
Edit:
If you right click on the pool Identity section and go to properties, it should come up with a box that lets you either choose from 3 builtin system accounts, or specify your own account. Either give one of the builtin accounts permission for the DB, or use an account that has permission. Or leave it as is and change your connection string.
Well...changing the ApplicationPoolIdentity property and setting it to NETWORK SERVICE seems to have fixed my problems. Not sure if that's the "right" way to do things or not (as in, I'm not sure if that's the recommended way to do things in IIS7 or not), but it seems to at least be working and has gotten me past this hang-up for now. Thanks.
I'm familiar with the idea of giving permissions to the user that the application is running under...my problem is that in IIS7, the "user" seems to be virtual or something strange like that. Prior to me changing the "Identity" property of the Application Pool properties to NETWORK SERVICE, it was set to "ApplicationPoolIdentity", and the error I was getting was that "IIS APPPOOL\MyApplicationName" didn't have access to the database. When I attempted to add the "IIS APPPOOL\MyApplicationName" user to the database, it didn't appear to exist...not that I could find anyway.
So my ultimate problem is not understanding or being able to find any good documentation on how the IIS7 security model works. When I created the application, it seemed to create an AppPool with the same name just for this application. I don't know exactly what changes I need to make to give the application and/or the user it runs under privileges to the database, considering the fact that the user that the AppPool runs as doesn't appear to actually exist.
As I mentioned, changing the Identity of the AppPool to NETWORK SERVICE seems to have worked for now, but I'm trying to find out what the best practice is for this kind of thing under IIS7. Thanks.
leave the hard problems for someone else -
create a sql user and use SQL Auth. :D
If you follow Mr. Fernández' advice, you will get everything working. This is the new way of giving least privilege to a site.
So don't do the easy, less secure thing (NETWORK SERVICE). Do the right thing. Scroll up. ;)
Using Trusted Connection in Windows Authenticated Mode:
OS: windows 7 32 bit
IIS 7, Sql Server 2008 R2 Express
Connection String:
cn.open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=test;Data Source=mycomputername\sqlexpress;" (if instance name is sqlexpress or whatever instance name you have used)
If you are not able to connect sql server using windows mode authenticated connection to sql server 2008.
NT AUTHORITY\IUSR Account might not have permission in sql server to authorize connection with database.
Connect Sql server using windows authentication mode.
Expand Security node.
Select NT AUTHORITY\IUSR (IF NOT THERE THEN ADD NEW LOG IN FOR THAT)
Click on "User Mapping" under Select a page at Log-in properties window.
Select the database that you are trying to connect.
Select following permissions from "Database role membership for:......"
1. db_datareader 'this allows to open connection
2. db_datawriter 'this allows to fetch data records from datatable
The first step is to verify which account your website is running under. Create a simple aspx page with:
<%# Page Language="C#" %>
<% Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name); %>
If you're using windows authentication the WindowsIdentity account will need to have a login in your SQL Server. Under Security -> Logins -> Login New you'll want to add whatever name that was displayed by WindowsIdentity and make sure Windows authentication is selected.
If you ever happen to move your database to a separate machine you'll have to create a domain account and use impersonation in your web.config. Google <identity impersonate="true"> for more info.
If you look in the description of the field it states that running under "Network Services" account is the recommended account to use. Not sure why in Win7 it defaults to the ApplicationPoolIdentity setting.
I have the exact same issue. I'm running Windows 7 RC. When I'm trying to usa a .mdf file (located in App_Data), there is now way to make that thing work. I did try to change the AppPool's identity for LocalSystem, but it simply won't work.
If I use a "standard" database, then it will work if I'm using LocalSystem, but it won't work with the famous 'IIS APPPOOL\DefaultAppPool'.
I find it a bit disturbing not to find any information on that matter, it seems that the 'IIS APPPOOL\DefaultAppPool' user is totally useless if you are using a database of any kind...
I have it running, but I'm also bit frustrated not to understand the security model, as stated by ryexley.
yes, the app pool identity method doesn't work like they say (not in IIS7 anyway) it's supposed to. I think there are hackers at MS who make this security convoluted on purpose so you take the path of least resistance and leave your system less secure (so they can hack into it later). - just kidding, but really, their security model is pure insanity, no straightforward (step by step) instructions anywhere on MSDN - nada, zip!
I faced same problem between (SQL2008 that is installed on standalone Win-server2003 server) and (IIS6 with ASP.NET3.5 that are installed on standalone Win-server2003 server).
Where, IIS tries to access SQL2008 using some user in the domain "domain\username".
I removed following option out of connectionstring, and every thing works fine now.
Integrated Security=True;
Open SQL Management Studio, connect to your local machine as an admin.
Expand the Security branch.
Right click on Logins and select New Login
Into the Login Name field, type "IIS APPPOOL\MyApplicationName". Do
NOT click the search button. The user profile dosn't actually exist
on the local machine, it's dynamically created on demand.
Select Database in User Mapping
Select sysadmin in Server Roles

Resources