These lines cause a security exception in a godaddy account. Any suggestions how to rewrite to get this to work?
File.Delete(PropsFileName); // Clean up
TextWriter tw = new StreamWriter(PropsFileName); // Create & open the file
tw.WriteLine(DateTime.Now); // Write the date for reference
tw.WriteLine(TokenLine); // Write the BinarySecurityToken
tw.WriteLine(ConvIdLine); // Write the ConversationId
tw.WriteLine(ipccLine); // Write the IPCC
tw.Close();
Thanks!
The information is being written to session.properties variable in the temp directory.
GoDaddy is set up to run under Medium trust, to simulate this on localhost add the following to your web.config:
<system.web>
<trust level="Medium" />
</system.web>
Something you can try to fix the issues is to add the following to your AssemblyInfo.cs under Project > Properties in solution explorer
[assembly: AllowPartiallyTrustedCallers]
Also here is an article that may or may not help you out and/or give you insight regarding a similar situation with NHibernate: NHibernate in a Medium Trust Environment
You should give NTFS permissions to the user running your ASP.NET app. Your hosting control panel probably supports assigning NTFS permissions to the folder.
Related
I am confused on how to modify the web.config appSettings values at runtime. For example, I have this appSettings section:
<appSettings>
<add key="productspagedesc" value="TODO: Edit this default message" />
<add key="servicespagedesc" value="TODO: Edit this default message" />
<add key="contactspagedesc" value="TODO: Edit this default message" />
<add key="aboutpagedesc" value="TODO: Edit this default message" />
<add key="homepagedesc" value="TODO: Edit this default message" />
</appSettings>
Let's say, I want to modify the "homepagedesc" key at runtime. I tried ConfigurationManager and WebConfigurationManager static classes, but the settings are "read-only". How do I modify appSettings values at runtime?
UPDATE:
Ok, so here I am 5 years later. I would like to point out that experience has told me, we should not put any configuration that intentionally is editable at runtime in the web.config file but instead we should put it in a separate XML file as what one of the users commented below. This will not require any of edit of web.config file to restart the App which will result with angry users calling you.
You need to use WebConfigurationManager.OpenWebConfiguration():
For Example:
Dim myConfiguration As Configuration = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~")
myConfiguration.ConnectionStrings.ConnectionStrings("myDatabaseName").ConnectionString = txtConnectionString.Text
myConfiguration.AppSettings.Settings.Item("myKey").Value = txtmyKey.Text
myConfiguration.Save()
I think you might also need to set AllowLocation in machine.config. This is a boolean value that indicates whether individual pages can be configured using the element. If the "allowLocation" is false, it cannot be configured in individual elements.
Finally, it makes a difference if you run your application in IIS and run your test sample from Visual Studio. The ASP.NET process identity is the IIS account, ASPNET or NETWORK SERVICES (depending on IIS version).
Might need to grant ASPNET or NETWORK SERVICES Modify access on the folder where web.config resides.
Changing the web.config generally causes an application restart.
If you really need your application to edit its own settings, then you should consider a different approach such as databasing the settings or creating an xml file with the editable settings.
And if you want to avoid the restart of the application, you can move out the appSettings section:
<appSettings configSource="Config\appSettings.config"/>
to a separate file. And in combination with ConfigurationSaveMode.Minimal
var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
config.Save(ConfigurationSaveMode.Minimal);
you can continue to use the appSettings section as the store for various settings without causing application restarts and without the need to use a file with a different format than the normal appSettings section.
2012
This is a better solution for this scenario (tested With Visual Studio 2008):
Configuration config = WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
config.AppSettings.Settings.Remove("MyVariable");
config.AppSettings.Settings.Add("MyVariable", "MyValue");
config.Save();
Update 2018 =>
Tested in vs 2015 - Asp.net MVC5
var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
config.AppSettings.Settings["MyVariable"].Value = "MyValue";
config.Save();
if u need to checking element exist, use this code:
var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
if (config.AppSettings.Settings["MyVariable"] != null)
{
config.AppSettings.Settings["MyVariable"].Value = "MyValue";
}
else { config.AppSettings.Settings.Add("MyVariable", "MyValue"); }
config.Save();
I know this question is old, but I wanted to post an answer based on the current state of affairs in the ASP.NET\IIS world combined with my real world experience.
I recently spearheaded a project at my company where I wanted to consolidate and manage all of the appSettings & connectionStrings settings in our web.config files in one central place. I wanted to pursue an approach where our config settings were stored in ZooKeeper due to that projects maturity & stability. Not to mention that fact that ZooKeeper is by design a configuration & cluster managing application.
The project goals were very simple;
get ASP.NET to communicate with ZooKeeper
in Global.asax, Application_Start - pull web.config settings from ZooKeeper.
Upon getting passed the technical piece of getting ASP.NET to talk to ZooKeeper, I quickly found and hit a wall with the following code;
ConfigurationManager.AppSettings.Add(key_name, data_value)
That statement made the most logical sense since I wanted to ADD new settings to the appSettings collection. However, as the original poster (and many others) mentioned, this code call returns an Error stating that the collection is Read-Only.
After doing a bit of research and seeing all the different crazy ways people worked around this problem, I was very discouraged. Instead of giving up or settling for what appeared to be a less than ideal scenario, I decided to dig in and see if I was missing something.
With a little trial and error, I found the following code would do exactly what I wanted;
ConfigurationManager.AppSettings.Set(key_name, data_value)
Using this line of code, I am now able to load all 85 appSettings keys from ZooKeeper in my Application_Start.
In regards to general statements about changes to web.config triggering IIS recycles, I edited the following appPool settings to monitor the situation behind the scenes;
appPool-->Advanced Settings-->Recycling-->Disable Recycling for Configuration Changes = False
appPool-->Advanced Settings-->Recycling-->Generate Recycle Event Log Entry-->[For Each Setting] = True
With that combination of settings, if this process were to cause an appPool recycle, an Event Log entry should have be recorded, which it was not.
This leads me to conclude that it is possible, and indeed safe, to load an applications settings from a centralized storage medium.
I should mention that I am using IIS7.5 on Windows 7. The code will be getting deployed to IIS8 on Win2012. Should anything regarding this answer change, I will update this answer accordingly.
Who likes directly to the point,
In your Config
<appSettings>
<add key="Conf_id" value="71" />
</appSettings>
in your code(c#)
///SET
ConfigurationManager.AppSettings.Set("Conf_id", "whateveryourvalue");
///GET
string conf = ConfigurationManager.AppSettings.Get("Conf_id").ToString();
Try This:
using System;
using System.Configuration;
using System.Web.Configuration;
namespace SampleApplication.WebConfig
{
public partial class webConfigFile : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Helps to open the Root level web.config file.
Configuration webConfigApp = WebConfigurationManager.OpenWebConfiguration("~");
//Modifying the AppKey from AppValue to AppValue1
webConfigApp.AppSettings.Settings["ConnectionString"].Value = "ConnectionString";
//Save the Modified settings of AppSettings.
webConfigApp.Save();
}
}
}
So I have a problem in my ASP.NET MVC application, it doesn't want to save the xml file after I publish it. I have a form which I post to a controller using ajax, and then I use that data to create an xml file which i then want to save.
I use the following code to generate my xml file and save it:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(rawXml);
StreamWriter path = new StreamWriter(Server.MapPath("/"+ fileName + ".xml"));
xmlDoc.Save(path);
If I run my application in debug It writes the file to ~/MySolution/MyProject/MyFile, no problem.
So when I publish the app to the IIS 7 server on my computer and load the app through localhost/MyApp, I expect it to write the file to C:\inetpub\wwwroot\MyApp\MyFile but it doesn't.
I have enabled permissions to the folder inetpub and all the subsequent folders for NETWORK SERVICE. But the AJAX post keeps returning in Error and the file doesn't appear in the folder, so I assume it's not allowing to write the file to the specified path, or the path is incorrect, ether way I don't know how to check what's gone wrong.
How do I make the published app write the xml file to the C:\inetpub\wwwroot\MyApp\MyFile path?
First of all it's not recommended to write any files in the root folder as writing to root folder cause appdomain to recycle after certain number of writes (default is 15) causing session loss. See more details here.
I would suggest you to add a path of your server to web.config and then fetch it in your code.Use something like below in the appsettings section of web.config
<add key="filePath" value="C:\inetpub\wwwroot\MyApp" />
Regarding the permissions please add Users group to your folder and give that group full permission (read/write).
To further find out which specific user (as there are too many use cases) is used by w3wp you can use process monitor as explained below
Capture Process Monitor log while reproducing issue
Filter on Access Denied
No Access Denied, so filter on w3wp.exe
Look for access to 401-3.htm
Review entries before the 401-3.htm to determine what file was accessed last
Check permissions based on successful QuerySecurityFile operation for last file accessed (in this case was asp.dll)
I have a code which is similar this:
string file;
using (StreamReader r = new StreamReader("xml.xml"))
{
file = r.ReadToEnd();
}
XElement xml = XElement.Parse(file);
using (XmlWriter w = XmlWriter.Create("xml.xml")) //The point of problem!
{
w.WriteStartDocument();
...;
w.WriteEndDocument();
}
When I try run it like a console application is everything all right. But problems start when I want to use it in an ASP.NET application. At the using line it throws UnauthorizedAccessException exception with a description "access to the path is denied". Why?
You need to check which account your application Pool is using to access your server files/folders, for example, make one code to copy one file to application folder, check all security info, copy and paste on this problem folder, normally use this account "IIS_IURRS" give full control to test only...
If IIS/the web server is configured correctly, an account with a very limited set of permissions is used. As your path points to the application directory, it is very likely that the application pool account is not allowed to write to this location.
If you run the code in a console application, your user's permissions are applied and it is more than likely that you are allowed to write to the output folder of the project as Visual Studio writes the build output there under your account.
I would not recommend to change the application pool account or the permissions of the application folder in the file system - it is a very sensible limitation that limits the amount of trouble an attacker can possibly make.
Therefore I'd recommend to either move the file to a folder that the account can write to without changing permissions or define a special one outside of the application folder hierarchy that the account is given permissions to.
Also keep in mind that multiple users might access the file at the same time, so a database might be a better choice to store the data.
I am trying to find the file path to web services that are not hosted in the normal Inetpub\wwwroot. I am wanting to find the version of the web services to check to make sure 2 PC have the same version which I have done now so long as I spiffy the exact file path or the web services are held in the normal spot. Unfortunately I have some PC that have the web services in multiple location so specifying the file path is not really possible. I can see that this type of question has been asked before(Get .svc file info of IIS web service on remote computer) but I cannot find answers to those questions.
Any idea would be greatly appreciated.
Edit: It is probable that what I am trying to do is actually not possible without having something on the target PC(an extra web method or a service or secondary app to pull the info). If that is the case that is fine, I am thinking about making to user point to the directory that has the web services on the remote PC which will work if it is very clunky for PCs with the web services in multiple directories.
Edit2: I have found a few more things that I feel like are getting me closer. What I have now is:
string path = "IIS://ServernameorIP/W3SVC";
DirectoryEntry w3svc = new DirectoryEntry(path, AdministratorUser, AdministratorUserPassword, 0);
w3svc.RefreshCache();//not sure if this is needed
foreach (DirectoryEntry entry in w3svc.Children)
{
//do some stuff to get the paths
}
This gets me some information, messing with the path gets me the sites I am looking for. I am not sure how still how to pull the physical path however. I am also having problems with the impersonation on the DirectoryEntry. I give it an administrator user and password and it still seems to send my local user and password as evidenced by the fact that those lines did not work until I added my user and password to the remote PC. Any help on either of those two would be greatly appreciated.
Thanks in Advance.
Looks like I have found where this information is stored. I have to use windows rather than IIS to give me the answer but I will be impersonating a local or domain administrator for use in this this app on the remote computer so it is not an issue for me in this case.
The ApplicationHost.Config file actually has the informaton that I need in the format:
<application path="/WebService_SomeWebService" applicationPool="DefaultAppPool">
<virtualDirectory path="/" physicalPath="C:\inetpub\wwwroot\WebService_SomeWebService" />
</application>
<application path="/WebService_SomeOtherWebService" applicationPool="DefaultAppPool">
<virtualDirectory path="/" physicalPath="C:\SomeotherFilepath\WebService_SomeOtherWebService" />
</application>
All I need to do is to pull that file from %windir%\System32\inetsrv\config and parse out the info that I need. Thanks to everyone who helped.
I'm calling the following code from Windows service that was written with C#:
try
{
ServerManager m = new ServerManager();
if(m != null)
{
SiteCollection sites = m.Sites; //I get exception here
}
}
catch (Exception ex)
{
}
I get this exception:
{"Filename: redirection.config\r\nError: Cannot read configuration
file\r\n\r\n":null}
What does that mean? And is there any way to predict it in ServerManager or my m variable before it's thrown?
Update: After looking at your comment now I can answer the question fully, the problem is your application is referencing the wrong Microsoft.Web.Administration.dll, seeing the error tells me you are referencing the IIS Express version and not the "full" IIS Version (7.0.0.0). So please modify your application code to add a reference to the one that is in c:\windows\system32\inetsrv\Microsoft.Web.Administration.dll instead.
This is a permissions problem.
You will need to make sure to run the Windows Service as an identity that is either a member of the Administrators group or SYSTEM. My guess is you might be running the service as Local Serivce or Network Service and those do not have permission to read the configuration files that sit in %windows%\system32\inetsrv\config.
Other Info:
Redirection.config is a file that IIS uses to determine if it should read its configuration from the normal path (%windir%\system32\inetsrv\config\applicationHost.config) or should read it from say an external UNC file share when centralized configuration is used for many servers. That is why this is one of the first files to be parsed and hence you get that access denied error for that specific file.
Regarding the predicting, the best thing to do would be to create it within a try/catch and handle that. There are many exceptions that could happen when reading configuration, such as permissions (you could predict this one by making sure you can read (say File.OpenText()) to Redirection.config, ApplicationHost.config in %windir%\system32\inetsrv\config but that is guessing and there are others such as access to encryption keys for passwords, invalid config, etc, etc.)