Securing web.config settings - c#

We are developing an ASP.NET MVC 5 application. We hired some remote developers to help us with the project.
The web.config file contains connection strings and app settings that we don't want to share with these remote developers. To work on our application, these developers remote into a development desktop that we control.
What is the best practice for securing sensitive information in web.config, so that developers can still run and debug application but not read the sensitive info in web.config?

Encrypting the web.config in a development environment is pointless. The only way to truely hide the information from the developers is not to give it to them in the first place.
You must ensure that your "remote development environment" is setup only to access a development database and is configured with other development settings only.
Don't check in any sensitive data (production passwords, etc) into your source control. You can achieve this by separating the information into external .config files so they are not checked into source control. TIP: Ignore the file with the actual passwords and add another one with the same name and an extension such as .config.example that is checked in to give the developer instructions on how to setup the file on their local system (which is a helpful reminder regardless of who sets up the system from a clone of the source control repository).
Use a continuous integration server (TeamCity, Jenkins, Octopus Deploy, etc) to build sensitive information into the release workflow through environment variables. Many CI servers have the ability to hide sensitive data from the UI. You can either practice automatic deployment via CI button-click so your developers don't have access to the sensitive data that is in the CI server, or give the deployment artifact(s) to a trusted team to install in production.
There is really no reason why a developer should even be given a chance to see sensitive production data such as passwords and private keys.

Like Ingenioushax suggested, the standard way of encrypting sections of web.config is using aspnet_regiis. Here is a tutorial.

How are you deploying your application?
If you use a tool such as Octopus Deploy - that only your onshore team have access to - you can use that to store any sensitive settings. These will get inserted into your configuration file during deployment.
In Octopus Deploy these are known as configuration variables.
This assumes that the sensitive settings are for environments other than ones that the developers will use themselves (Production and UAT, for example).

You can store config variables in environment variables and read them into the app at run time - this is better because each developer and environment can have their own configs that will never collide with others.

Related

How to configure C# WinForms application to get EnvironmentName that it is deployed to on Azure?

This question is related to: .NET Core console application, how to configure appSettings per environment?
Question
How do I make a WinForms application environment-aware based on the different subscriptions that we have setup?
Context
I am finding very little documentation and examples on how to handle the deployment of Winforms applications to an Azure VM across multiple subscriptions. For example, if I deploy the Winforms application to a subscription that is marked as development, then it should use both the security groups and the SQL Server that is tied to the Development subscription. Rinse and repeat for UAT and Production.
Currently, we have a WinForms application that has multiple appsettings.<env>.json files for development, UAT, and production. We are using SlowCheetah to transform the appsettings.json file based on what the Configuration Manager says. This appears to be tied to the buildConfiguration parameter in the MsBuild pipeline task. We have different environment values in the appsettings files for the SQL Server connection string and security groups.
The application it intended to be deployed through a virtual machine and the environments are subscription-specific. How do we configure each subscription to contain the corresponding environment name and then pass that to the application on runtime? Would we still use SlowCheetah and set the environment through the buildConfiguration parameter in the MsBuild task, or would we do something else?
It seems like we can either go that route or we can use the Environment Variables route, but I don't see how the environment variable can be set for a virtual machine in Azure. Any help, documentation, or examples that I can pursue is greatly appreciated!
Note: for a web-application, this seems pretty straight-forward. Just setup the ASPNETCORE_ENVIRONMENT variable in both the project and in the Configuration within the App Service on Azure.
As clarified in the comments, and if I understand you correctly, you want to set environment options in Azure Portal and have them visible to programs running within the VM.
Note that Azure Virtual Machines are just Infrastructure as a Service - they're kinda bare with minimal Azure services provided on-top, consequently there's no notion of a VM being in Production or Staging - that's all up to you to implement yourself.
That said, you can set some configuration values in the Azure Portal (and through PowerShell) which are passed-on to the VM: this can be done using the "User Data" area of your VM's configuration area.
Note this only applies to ARM (Azure Resource Manager) VMs, not "Classic" VMs or "Cloud Service" AMs.

How to make file references to local disk work in Azure Web Site?

In my Azure Web Site I have in my AppSettings section in Web.Config some references to files on my disk. When deployed to Azure those references doesn't count any more. I know that you can overwrite AppSettings in Web.Config in the Azure environtment. But what is the file structure there?
A couple of examples from my web.config that I have to solve:
<add key="DataMapPath" value="d:\inetpub\MyWebApp\App_Data\map.xml"/>
<add key="CuteWebUI.AjaxUploader.TempDirectory" value="C:\Temp\WebApp\Attachments\UploaderTemp"/>
The first file tells our code to look for the map.xml-file in the App_Data-directory.
The last one tells our upload-controll where to upload files. I maybe should have used Azure Blob Storage here instead but that would need some major refactoring of our code.
Is there som best practices on this topic?
Our WebApp is running in production today, but I want to try out MS Azure. But I doesn't want to do to many code changes to make it work in Azure.
I have also read you can spin up an Virtual Machine (Windows Server) but that is overkill for my needs right now. We may go that way in the end, but for this testing-purpose it should be made simple.
Any suggestions on how this could be solved? Someone done this before? I guess someone has. Indeed.
If I do have read and write access to the file system for my Web Site I maybe could use this:
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TheFolder");
This would be appropriate for both on-premise and Azure deployment. But then I have to do some changes in our code.
You have multiple options:
Option 1: Use the App Settings of your web app to set custom settings for your website.
Option 2: Create multiple versions of your web.config (Visual Studio supports this) and deploy different versions to Azure and your local machine
Option 3: Make your path's relative to the paths of Azure Web App's environment variables
There's a HOME environment variable in your Azure Web App that resolves to the equivalent of inetpub for your site. Your app data folder is located at %HOME%\site\wwwroot\AppData.
There's also a TEMP environment both on Azure Web Apps and on your local machine. You can make your second setting relative to the TEMP environment variable value.
Actually you won't have this kind of "control" using azure web sites. To keep your app as it is, use Azure Virtual Machines.

Multiple azure websites on same application?

I have a web app that I need to deploy on different websites.
Conditions:
The application code is identical across all websites;
The application is database driven;
Different websites have to connect to different databases;
Connection strings for databases are defined in web.config.
How can I make different websites use the same deployment of the application with different web.config to pull data from different databases?
Here is what my control panel looks like now:
These websites are all applications that I publish separately out of Visual Studio.
The end goal is this:
I found this article: http://www.wadewegner.com/2011/02/running-multiple-websites-in-a-windows-azure-web-role/
It talks briefly about this in “Run the Same Project in Two Sites in the Web Role”
But it seems like this is supposed to be for a local setup and does not discuss how I can get this on the remote Azure instance.
This seems pretty straight forward. Not sure what exactly your issue is.
You can easily map (Deploy from source control) multiple Azure Web Sites to same source code repository. Then, if you are using VSO (Visual Studio Online), the linking will create a new CI build definition for each site. Then you only have to edit the Build Configuration to include the appropriate configuration settings for each environment.
If you are using other source control, you can still customize how the continuous deployment works. All the settings are configurable via a special .dpeloyment file. You can read more about these configurable settings here. Most important part:
SCM_BUILD_ARGS=-p:Configuration=Debug;PublishProfile=MyChainedTransform
You can change build configuration to match that of the target site.
Now, how to make this independently of the source control. Nice Kudu Gurus have thought about that, too. You can tweak these settings via Application Setting for the web site itself (check section Using App Settings instead of .deployment file:
Instead, you can use App Settings to set the same values that are supported
in the .deployment file. The steps are:
Go to the Configure tab for you site in the Azure portal
Add an App Setting called Project, and set its value to something like
WebProject/WebProject.csproj
Then in your other web site you can set Project to point to a different .csproj file.
So you add a new entry with key SCM_BUILD_ARGS and value -p:Configuration=<your_desired_configuration> in the Site Application Settings and you should be ready to go.
Disclaimer: have not check the solutions, but there is no reason why either should not work.

How can I access server-level IIS connection settings programatically from within a .NET class?

Background
We are using a reporting tool which is .NET based.
The reporting tool uses a settings file which is a pain to update between environments (doesn't do transformations, etc.)
The reporting tool allows us to write .NET plugins to be run at certain times so I can modify the settings file on the fly
We have access to IIS and can add settings / connection strings at that level
Goal
I'd like to:
Simplify deployment by moving all connection strings & settings to the IIS server-level settings.
even our developers have IIS available locally so this won't be a problem for them.
Use the .NET plugin that I'm writing to connect to the server the app resides on and pull the connection strings and settings files.
Question
How can I access server-level IIS connection settings programatically from within a .NET class?
Notes / Things to Consider
This application does not use a web.config.
EDIT: While apparently the app doesn't use a web.config, one does exist when the app is deployed, so theoretically I could access it via the .NET plugin.
These are actually technically 5 different web sites. I'll be implementing the plugin the same way for each web site
The IIS servers are only used for this purpose, so I'd like the settings & configuration elements to be global across all of the web applications.
you can use Memory Cache, MemoryCache class has been changed to make it usable by .NET Framework applications that are not ASP.NET applications.

In a given C# Windows Forms application/WPF, where are user settings usually stored?

I was thinking either:
An Appconfig file
A generic .XML file and have the program load values at launch.
What is the best way to do this? A website with a best user tutorial perhaps?
Please see Using Settings in C#:
The .NET Framework 2.0 allows you to
create and access values that are
persisted between application
execution sessions. These values are
called settings. Settings can
represent user preferences, or
valuable information the application
needs to use. For example, you might
create a series of settings that store
user preferences for the color scheme
of an application. Or you might store
the connection string that specifies a
database that your application uses.
Settings allow you to both persist
information that is critical to the
application outside of the code, and
to create profiles that store the
preferences of individual users.
The answer to your question depends on the persistence model for the settings:
are settings per-user based or machine-wide?
are settings application specific or can/do they need to be used/discovered by other applications as well?
are settings default values known at design time or are they generated at install time?
are settings local to particular machine or can/will they be roamed?
The standard .NET settings support local per-user settings (when the user runs as a regular user) and local machine-wide settings (when the user runs as administrator), both with build-time machine-wide default values and for application-use only. This addresses the majority of scenarios. There is some advanced functionality there which allows to use the .NET Configuration classes with configuration files in different locations, which can allow for roamable and third-party discoverable settings as well; however, there is no Visual Studio tooling support for such scenarios.

Categories

Resources