Handle multiple web.configs based on URL - asp.net

We currently have an application which is used against multiple regional databases. The codebase is exactly the same but it is rolled out on the webserver in 3 different directories each with its own web.config (to hit the correct database and get correct app settings). Each with its own IIS environment.
However, my manager wants this changed i.e. One IIS application which will dynamically load up the correct web.config file for each region.
I will attempt to load the correct web.config file based on a query parameter when logging in but I have no idea on how to load the web.config file when logging in.
Anyone with experience doing this .... is there a better solution?

Based on your comment here's a different approach. You have a little work to do.
Routing all the domains to the same web site
I'm assuming you have one domain name per region (e.g. Region1.WebSite.com, Region2.WebSite.com, etc.) Combining these into one physical web site is a little tricky because of SSL certificate required. Has to match.
Two options:
Drive all three domains to the same web server via three different internal IP addresses. This means three sets of bindings in IIS and three different certs.
Use SSL offloading and terminate SSL at the load balancer. Direct all three sites to the same internal IP address on IIS. Make sure you have configured the LB to forward the original host header.
Detect where the request came from
In ASP.NET code, you can use the host header to see what domain the request was submitted over, e.g.
var siteRequested = Request.Headers["Host"];
Use the host header to pick a connection string
You will need several entries in web.config, one for each connection string. Format the name of the connection string to include the host name, so that you can obtain the right string by using something like this:
var configItemName = "ConnectionString." + Request.Headers["Host"];
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[configItemName].ConnectionString;
Your web.config connection strings should look something like this:
<connectionStrings>
<add name="ConnectionString.Region1.WebSite.com" connectionString="Data Source=serverNameForRegion1;Et Cetera" />
<add name="ConnectionString.Region2.WebSite.com" connectionString="Data Source=serverNameForRegion2;Et Cetera" />
<add name="ConnectionString.Region3.WebSite.com" connectionString="Data Source=serverNameForRegion3;Et Cetera" />
</connectionStrings>
Store any remaining region-specific configuration in the database
Each database will have its own copy of configs, so you just need to retrieve them using the correct connection string and you'll get the right configs.

You can keep a common web.config, but then move a portion of it to a separate file, using ConfigSource. See this question for details.
Once you have some configs in a separate file, you can choose a different file at runtime:
In ASP.NET applications, at run time you can assign to the ConfigSource property the name of an alternative configuration file.
Link

Related

ASP.NET_SessionId cookie disappearing between request on a specific server

I have differing behavior between a test server and a dev server - on my dev server everything works fine but on the test server the ASP.NET_SessionId cookie disappears after a flow of events and hence so does the servers session. Testing was done in the same browser on the same machine & the code bases are virtually identical. The only significant difference is that the pages are being served from two different pcs.
The flow of pages (all https) that causes this is such:
Load page from domain A that contains an iframe (session cookie exists at this point).
Domain B is loaded into the iframe.
A second page from domain B is loaded into the iframe triggered from the first page.
The second page does a form post to back to domain A where the session cookie is now absent.
EDIT
Forgot to say - we're using SqlInMemoryProvider as our session state.
You could share the session state between two servers using the below ways:
1)Using SQLServer Session:
In this mode of session state, the session objects are stored into SQL Server.
The benefit of using this technique is that all the data in the session will be stored together in a different location or you can say a centralized location in SQL Server, to get it working we just need to configure the SQLServer to store session data.
2)Using the StateServer Session:
In this mode of session state, the session objects are stored in a separate server handled by a Windows Service running on that server.
The benefit of using this technique is that all the data in the session will be stored together in a different location. In this case, the server to be handled by the Windows Service is named "aspnet_state"; this will become the centralized location for session data. To get it working we just need to configure the StateServer to store Session data.
when you share the session state between two servers make sure ASP.NET state service is installed on all the servers and the settings are as below:
Also, the service cannot be accessed remotely by default. To enable that option you need to set the value of the following registry key to 1: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection. Don’t forget to restart the asp.net state service after the registry key change.
You need to declare the session management options within the system.web node. Example:
<sessionState mode="StateServer" stateConnectionString="tcpip=machinename:42424">
</sessionState>
If you want to use the SQL Server type then this section may look like the following:
<sessionState mode="SQLServer" allowCustomSqlDatabase="true"sqlConnectionString="the connection string name to the server">
</sessionState>
Where SQL connection string refers to the name of the connection string in the connectionStrings section of web.config which holds the details of the state table. The connection string itself may take up the following format:
<add name="ASPStateConnectionString" connectionString="Data Source=[DB machine name where state DB is stored];Initial Catalog=ASPState;User ID=[db admin user name];Password=[db admin password]"providerName="System.Data.SqlClient" />
we also need to add a machine and a validation key within the system.web node, that may look something like this:
<machineKey
validationKey="some long hashed value"
decryptionKey="another long hashed value"
validation="SHA1"/>
The default setting for the validation key is AutoGenerate which does exactly what the name applies: the key will be generated automatically by IIS. The default generation mode for the decryption key is IsolateApps. It generates a unique key for each application by using the application ID.
We need this common machine key as we want to run this on several machines so we don’t want the machine key to be automatically generated.
For more information you could refer this below links:
https://dotnetcodr.com/2013/07/01/web-farms-in-net-and-iis-part-5-session-state-management/
https://www.c-sharpcorner.com/UploadFile/25c78a/load-balancing-session-state-configuration/
It's because cookies are not stored if domains are different.
It's treated as 3rd party cookies.
You need to use same domain as parent site to iframe site.
Or else you need to use cookieless session.
I have recently gone through this problem and come across the concept of cross-site cookies. If you want to share and use the cookie across the different domains then you have to set your cookie samesite attribute to None (SameSite=None). It must be secure otherwise it will be ignored and not send back to the server by browser (Chrome). To use a secure tag for your cookie you have to enable the HTTPS for your website.
For more detail you visit: https://web.dev/samesite-cookies-explained/

Needed Update to Server or Website to support AWS Certificate Rotation

I've received an email from Amazon Web Services regarding certificate rotation. I need to know whether I should make any changes to my EC2 or Web.config to make it support the new database certificate.
Rotating your SSL/TLS certificate: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL-certificate-rotation.html
Updating Applications to Connect to Microsoft SQL Server DB Instances Using New SSL/TLS Certificates: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/ssl-certificate-rotation-sqlserver.html
A sample connection string from the Web.config that I use (sensitive data omitted).
<add name="temp" connectionString="Server=someaddress.us-east-3.rds.amazonaws.com;
Port=3306;Database=somedatabase;Uid=someuserid;Pwd=somepassword" providerName="MySql.Data.MySqlClient" />
All my websites have a similar connection string that connects to the RDS database server.
Is there any change needed to be made to the web.config or the EC2 server to make my websites support the new certificate rotation.
You don't need to make any changes since you are not using SSL certificate to connect to RDS. your website will continue to work as it is now without making any changes to your config. But you can consider using SSL to connect to your RDS in order to improve security in the future.
As long as you aren't using an SSL connection to your database, the certificate won't be used and you can update the certificate without any side effect.
This would have been the case if your connectionString included an sslmode as required:
<add
name="mySql"
providerName="MySql.Data.MySqlClient"
connectionString="...;SslMode=Required;" />
Since this is not the case, you can update your certificate right away.
Yes Web.config needs to changed definitely.The changes required are listed below.There might be additional changes based on the security group and vpc setup you have done.
You need to add SslMode=Required parameter to the connectionString
Also add a parameter SslCa=ca.pem
Download the https://s3.amazonaws.com/rds-downloads/rds-ca-2019-root.pem file from aws.

The remote certificate is invalid according to the validation procedure. Identity Server

On one computer I have 2 projects - a client application and another that holds the identity server and identity manager. When I run the client site on this computer everything works. I am able to sign in, register etc. This project was already set up and working.
I made a copy of the projects and put them on another computer. I have set the sites up in IIS and created a self signed certificate.
When I run the client site and attempt to sign in I get the yellow asp.net error page with the message "The remote certificate is invalid according to the validation procedure". When stepping through with the debugger I also see: "The underlying connection was closed: could not establish trust relationship for the ssl/tls secure channel"
I figure the errors have to do with the certificate so in MMC I made sure that the certificates are installed in the trusted root certification authorties folder.
The other thing I did was check the web.config files in the projects.
In the client site I have something like:
<oidcClient clientId="codeclienthere"
clientSecret="secrethere"
signingCertificate="keythatmatches_certificate_hash_here"
issuerName="https://identityurlhere/issuer"
...
Then in the identity server and identity manager web.config files I have something like:
<appSettings>
<add key="owin:AppStartup" value="startup" />
<add key="Issuer" value="identity_url_here/issuer" />
<add key="Thumbprint" value="‎‎keythatmatches_certificate_hash" />
<add key="WebClientId" value="codeclienthere"/>
<add key="WebClientSecret" value="secrethere"/>
...
I changed the signing certificate and thumbprint values to match the certificate hash. For the attribute "issuerName" and key "Issuer" I tried leaving it the same, setting it the name of the certificate and prepending "CN=" to the name of the certificate. I am unsure what value should go here. I am also unsure what other things I should check.
The problem here was that there were hidden characters in the thumbprint that I did not notice. I had pasted in a text editor to compare or something and they got removed so when I pasted them back in the config file they did not match as needed.

Active Directory membership provider using LDAP

I am working on a school assignment where we handle logins to a web application written in asp.NET using Active Directory. Our Active Directory is installed on a virtual machine on Azure.
When trying to login, I am presented with the following error:
I have checked my connection string multiple times, and can't seem to get it to work.
Currently, I have the following connection string:
<add name="ADConnectionString" connectionString="LDAP://ictforevents1.cloudapp.net/DC=ictforevents1,DC=cloudapp,DC=net" />
The DNS name assigned to our virtual machine is ictforevents1.cloudapp.net, which is also the domain I set up in the Active Directory setup wizard.
Using the data in the connection string above, I can connect to the AD using LDAP Admin.
How to fix the error?
I fixed the issue by replacing the domain with the IP address in the connection string. From what I could find, asp will always always try to use a secure connection, even when using the insecure port (389). It will not attempt this when an IP address is given.
My new connection string is:
<add name="ADConnectionString" connectionString="LDAP://23.97.173.160:389/CN=Users,DC=ictforevents1,DC=cloudapp,DC=net" />
While this is not ideal, because the server does not have a static IP, it's better than not working at all.

instance failure error in asp.net web site

I have a website included login module.when i hosted the website in iis there is an error
Server Error in "/" Application.
system.invalid operation Exception: Instance Failure
My ConnectionString is like this
<add name="MyConnectionstring" Connectionstring="Data Source=IP Address,1433;Network Library=DBMSSOCN;initial catalog=Databasename;integrated security=True" Provider Name="System.data.sqlclient"/>
How can i solve this problem?Any one knows Please help me
Simply change DataSource=My-PC\\\SqlServer2008 to DataSource=My-PC\SqlServer2008 in your Web config because the previous one is valid one you are writing in Code Beind file but not in Web config file as it is an XML file.
The first thing I noticed is that you need to replace IP Address in your connection string with the actual IP address and Databasename with the actual database name. You also don't need ",1433" after the IP Address since 1433 is the standard port.
Second, is the SQL you are connecting to the default instance on the machine? If it is a named instance, you need to make sure to include the name in the data source setting.
Third, does the ID the ASP.NET process is running under have authority to connect to the SQL Server instance?

Resources