Where should a .NET Web Application store it's (non database) setting - asp.net

I am building a Web Application that will be installed many times. The application needs to be able to save certain setting itself upon request.
I have an installer (InnoSetup) but I want to very careful about what permissions I give the Web Application.
I can't use a database.
A default install always leaves the web.config as read-only. (Most secure)
The registry can be problematic. Unless there is a set of keys a DotNet webapp can always write to by default (IIS_IUSR)...
I was considering App_Data, but the default permissions are no longer useful and Inno-Setup can't easily fix it correctly:
https://support.microsoft.com/en-us/kb/2005172
Security and Ease of Setup are both big issues..
I also don't want to make a mess of the machines I install to.
A FAILED solution was to write to the user portion of the registry:
Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Software\\MyCo\\MyApp\\");
var reg = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\MyCo\\MyApp", true);
reg.SetValue("MyValue", (string)dataString, Microsoft.Win32.RegistryValueKind.String);
But I found out that writing to HKEY_CURRENT_USER is also not allowed by default on Server 2012 and likely others. The server error page is helpful and gives options such as explicitly giving the IUSR_{MachineName} explicit permission but this is a no go for me.
So my final solution is to have the installer create a user configurable folder and then assigning all users Read/Write access to that folder. The administrator can always lock it down more if they want.
If anyone has a better option then let me know.

With InnoSetup I created a new Wizard page to suggest and collect a Data folder from the user. The installer then:
Created that folder and gave All Users Read/Write access,
Added a HKLM registry key telling the Web App where to look for the folder,
Notified the user that they should lock the folder down further to prevent abuse.

Related

ASP.NET app cannot see files

I have an ASP.NET web app (VS 2017 Framework 4.5) that works fine in development. When I deploy to the web server and try to reference a file like this:
PdfBitmap tiffImage = new PdfBitmap(item.TIFPageLocation);
It returns a "Can't find file error". I even set up an if File.Exists() test and had the same result.
The file is a reference to another server like this: \\myserver\myvolume1\00\12\7A\00127A90.TIF.
When I run this path on the web server in WinExplorer it finds and open the TIF image in the default viewer. However the web app cannot see it for some reason.
This is likely some permissions issue but I'm not sure where.
Any ideas?
Thanks
Carl
Yes, this is likely a permissions issue. Your web app will probably be running under an account that has limited rights (almost certainly without the rights to access anything on the domain).
You either need to:
a) elevate their rights (be very careful with this)
b) run your site under a new user context created specifically for this site with rights to reach the other server
c) put your images somewhere easier to access.
Check your folder permission it should not have read access cross check that it's worked for me
It was the account the app pool identity was associated with. That need to be set properly.

Sharing data files between users in a Universal Windows Platform application

I am about to embark on the development of a line of business application using the Universal Windows Platform (Windows 10). One of the requirements of the application is the synchronisation of data from a server to a local SQLite database; this is required because the application needs to be usable where there is no network connectivity.
It is likely that multiple (windows domain) users will be accessing the application on the same device, sometimes simply by "swapping users", other times by logging off the first user and logging on as a new user.
I realise that UWP applications are installed at a user level, however I would like to be able to share the SQLite database between these users instead of forcing each user to download their own copy of the data.
Is this possible? I am struggling to find any reference to this kind of sharing within the Microsoft documentation - but of course that documentation is new and far from complete!
I guess at the end of the day I am looking for access to a folder that is accessible by any user running that application on the same device, such as the "x:\Users\Public" folders that are available from the desktop, but without having to ask the user to provide access to that folder via any picker control - instead simply being able to "open" it.
Thanks.
In case anyone runs across this, this functionality is now available as described in this blog post:
We introduced a new storage location Windows 10, ApplicationData.SharedLocalFolder, that allows multiple users of one app to share local data. Obviously this feature is only interesting with devices that will be used by more than one person. For such scenarios, for example in educational uses, it may make sense to place any large downloads in Shared Local. The benefits will be two-fold: any user can access these files without the need to re-download them, also there will be storage space savings
Keep in mind that Shared Local is only available if the machine has the right group policy, otherwise when you call ApplicationData.Current.SharedLocalFolder you will get back a null result.
In order to enable Shared Local the machine administrator should enable the corresponding policy.
Alternatively, the administrator could create a REG_DWORD value called AllowSharedLocalAppData with a value of 1 under HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager
Note that data store in ShareLocal will only be persisted as long as the app is installed on the device and won’t be backed up by the system.
In Solution Explorer , Right click on Package.appxmanifest then click on ViewCode , end of this file in both projects add below code :
<Extensions>
<Extension Category="windows.publisherCacheFolders">
<PublisherCacheFolders>
<Folder Name="FolderName" />
</PublisherCacheFolders>
</Extension>
</Extensions>
After that in code you can access this folder with below line of code :
StorageFolder sharedDownloadsFolder = ApplicationData.Current.GetPublisherCacheFolder("FolderName");
It`s so important that the folder you will share between two these Apps depend on same publisher info at Certificate File [ProjectName]_TemporaryKey.pfx , if this Certificate File and publisher Info of app is same in both Projects , then you can access the same SharedFolder in both application and use it for create or use dataBase file(like SQLite Database file) or other files that need to be share in both applications.

System.Security.SecurityException when writing to Event Log

I’m working on trying to port an ASP.NET app from Server 2003 (and IIS6) to Server 2008 (IIS7).
When I try and visit the page on the browser I get this:
Server Error in ‘/’ Application.
Security Exception
Description: The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application’s trust level in the configuration file.
Exception Details: System.Security.SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and the location of the exception can be identified using the exception stack trace below.
Stack Trace:
[SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security.]
System.Diagnostics.EventLog.FindSourceRegistration(String source, String machineName, Boolean readOnly) +562
System.Diagnostics.EventLog.SourceExists(String source, String machineName) +251
[snip]
These are the things I’ve done to try and solve it:
Give “Everyone” full access permission to the key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Security. This worked. But naturally I can’t do this in production. So I deleted the “Everyone” permission after running the app for a few minutes and the error re-appeared.
I created the source in the Application log and the Security log (and I verified it exists via regedit) during installation with elevated permissions but the error remained.
I gave the app a full trust level in the web.config file (and using appcmd.exe) but to no avail.
Does anyone have an insight as to what could be done here?
PS: This is a follow up to this question. I followed the given answers but to no avail (see #2 above).
To give Network Service read permission on the EventLog/Security key (as suggested by Firenzi and royrules22) follow instructions from http://geekswithblogs.net/timh/archive/2005/10/05/56029.aspx
Open the Registry Editor:
Select Start then Run. Enter regedt32 or regedit
Navigate/expand to the following key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security
3. Right click on this entry and select Permissions
Add the Network Service user
Give it Read permission
UPDATE: The steps above are ok on developer machines, where you do not use deployment process to install application.
However if you deploy your application to other machine(s), consider to register event log sources during installation as suggested in SailAvid's and Nicole Calinoiu's answers.
I am using PowerShell function (calling in Octopus Deploy.ps1)
function Create-EventSources() {
$eventSources = #("MySource1","MySource2" )
foreach ($source in $eventSources) {
if ([System.Diagnostics.EventLog]::SourceExists($source) -eq $false) {
[System.Diagnostics.EventLog]::CreateEventSource($source, "Application")
}
}
}
See also Microsoft KB 2028427 Fail to write to the Windows event log from an ASP.NET or ASP application
The problem is that the EventLog.SourceExists tries to access the EventLog\Security key, access which is only permitted for an administrator.
A common example for a C# Program logging into EventLog is:
string sSource;
string sLog;
string sEvent;
sSource = "dotNET Sample App";
sLog = "Application";
sEvent = "Sample Event";
if (!EventLog.SourceExists(sSource))
EventLog.CreateEventSource(sSource, sLog);
EventLog.WriteEntry(sSource, sEvent);
EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning, 234);
However, the following lines fail if the program hasn't administrator permissions and the key is not found under EventLog\Application as EventLog.SourceExists will then try to access EventLog\Security.
if (!EventLog.SourceExists(sSource))
EventLog.CreateEventSource(sSource, sLog);
Therefore the recommended way is to create an install script, which creates the corresponding key, namely:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App
One can then remove those two lines.
You can also create a .reg file to create the registry key. Simply save the following text into a file create.reg:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App]
The solution was to give the "Network Service" account read permission on the EventLog/Security key.
For me ony granting 'Read' permissions for 'NetworkService' to the whole 'EventLog' branch worked.
I had a very similar problem with a console program I develop under VS2010 (upgraded from VS2008 under XP)
My prog uses EnLib to do some logging.
The error was fired because EntLib had not the permission to register a new event source.
So I started once my compiled prog as an Administrator : it registered the event source.
Then I went back developping and debugging from inside VS without problem.
(you may also refer to http://www.blackwasp.co.uk/EventLog_3.aspx, it helped me
This exception was occurring for me from a .NET console app running as a scheduled task, and I was trying to do basically the same thing - create a new Event Source and write to the event log.
In the end, setting full permissions for the user under which the task was running on the following keys did the trick for me:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog
I try almost everything in here to solve this problem... I share here the answer that help me:
Another way to resolve the issue :
in IIS console, go to application pool managing your site, and note the identity running it (usually Network Service)
make sure this identity can read KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog (rigth-click, authorisations)
now change the identity of this application pool to Local System, apply, and switch back to Network Service
Credentials will be reloaded and EventLog reacheable
in http://geekswithblogs.net/timh/archive/2005/10/05/56029.aspx , thanks Michael Freidgeim
A new key with source name used need to be created under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application in the regEdit when you use System.Diagnostics.EventLog.WriteEntry("SourceName", "ErrorMessage", EventLogEntryType.Error);
So basically your user does not have permission to create the key. The can do the following depending of the user that you are using from the Identity value in the Application Pool Advanced settings:
Run RegEdit and go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog
Right click in EventLog key and the select Permissions... option
3.Add your user with full Control access.
-If you are using "NetworkService" add NETWORK SERVICE user
-If you are usinf "ApplicationPoolIdentity" add IIS APPPOL{name of your app pool} (use local machine location when search the user).
-If you are using "LocalSystem" make sure that the user has Administrator permissions. It is not recommend for vulnerabilities.
Repeat the steps from 1 to 3 for HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security
For debugging with Visual Studio I use "NetworkService" (it is ASP.NET user) and when the site is published I used "AppicationPoolIdentity".
I ran into the same issue, but I had to go up one level and give full access to everyone to the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\ key, instead of going down to security, that cleared up the issue for me.
Same issue on Windows 7 64bits.
Run as administrator solved the problem.
There does appear to be a glaringly obvious solution to this that I've yet to see a huge downside, at least where it's not practical to obtain administrative rights in order to create your own event source: Use one that's already there.
The two which I've started to make use of are ".Net Runtime" and "Application Error", both of which seem like they will be present on most machines.
Main disadvantages are inability to group by that event, and that you probably don't have an associated Event ID, which means the log entry may very well be prefixed with something to the effect of "The description for Event ID 0 from source .Net Runtime cannot be found...." if you omit it, but the log goes in, and the output looks broadly sensible.
The resultant code ends up looking like:
EventLog.WriteEntry(
".Net Runtime",
"Some message text here, maybe an exception you want to log",
EventLogEntryType.Error
);
Of course, since there's always a chance you're on a machine that doesn't have those event sources for whatever reason, you probably want to try {} catch{} wrap it in case it fails and makes things worse, but events are now saveable.
FYI...my problem was that accidently selected "Local Service" as the Account on properties of the ProcessInstaller instead of "Local System". Just mentioning for anyone else who followed the MSDN tutorial as the Local Service selection shows first and I wasn't paying close attention....
I'm not working on IIS, but I do have an application that throws the same error on a 2K8 box. It works just fine on a 2K3 box, go figure.
My resolution was to "Run as administrator" to give the application elevated rights and everything works happily. I hope this helps lead you in the right direction.
Windows 2008 is rights/permissions/elevation is really different from Windows 2003, gar.
Hi I ran into the same problem when I was developing an application and wanted to install it on a remote PC, I fixed it by doing the following:
1) Goto your registry, locate: HKLM\System\CurrentControlSet\Services\EventLog\Application(???YOUR_SERVICE_OR_APP_NAME???)
Note that "(???YOUR_SERVICE_OR_APP_NAME???)" is your application service name as you defined it when you created your .NET deployment, for example, if you named your new application "My new App" then the key would be: HKLM\System\CurrentControlSet\Services\EventLog\Application\My New app
Note2: Depending on which eventLog you are writing into, you may find on your DEV box, \Application\ (as noted above), or also (\System) or (\Security) depending on what event your application is writing into, mostly, (\Application) should be fine all the times.
2) Being on the key above, From the menu; Select "FILE" -> "Export", and then save the file. (Note: This would create your necessary registry settings when the application would need to access this key to write into the Event Viewer), the new file will be a .REG file, for the argument sake, call it "My New App.REG"
3) When deploying on PRODuction, consult the Server's System's administrator (SA), hand over the "My New App.REG" file along with the application, and ask the SA to install this REG file, once done (as admin) this would create the key for your applicaion.
4) Run your application, it should not need to access anything else other than this key.
Problem should be resolved by now.
Cause:
When developing an application that writes anything into the EventLog, it would require a KEY for it under the Eventlog registry if this key isn't found, it would try to create it, which then fails for having no permissions to do so. The above process, is similar to deploying an application (manually) whereas we are creating this ourselves, and no need to have a headache since you are not tweaking the registry by adding permissions to EVERYONE which is a securty risk on production servers.
I hope this helps resolving it.
Though the installer answer is a good answer, it is not always practical when dealing with software you did not write. A simple answer is to create the log and the event source using the PowerShell command New-EventLog (http://technet.microsoft.com/en-us/library/hh849768.aspx)
Run PowerShell as an Administrator and run the following command changing out the log name and source that you need.
New-EventLog -LogName Application -Source TFSAggregator
I used it to solve the Event Log Exception when Aggregator runs issue from codeplex.
Had a similar issue with all of our 2008 servers. The security log stopped working altogether because of a GPO that took the group Authenticated Users and read permission away from the key HKLM\System\CurrentControlSet\Services\EventLog\security
Putting this back per Microsoft's recommendation corrected the issue. I suspect giving all authenticated users read at a higher level will also correct your problem.
I hit similar issue - in my case Source contained <, > characters. 64 bit machines are using new even log - xml base I would say and these characters (set from string) create invalid xml which causes exception. Arguably this should be consider Microsoft issue - not handling the Source (name/string) correctly.
My app gets installed on client web servers. Rather than fiddling with Network Service permissions and the registry, I opted to check SourceExists and run CreateEventSource in my installer.
I also added a try/catch around log.source = "xx" in the app to set it to a known source if my event source wasn't created (This would only come up if I hot swapped a .dll instead of re-installing).
Solution is very simple - Run Visual Studio Application in Admin mode !
I had a console application where I also had done a "Publish" to create an Install disk.
I was getting the same error at the OP:
The solution was right click setup.exe and click Run as Administrator
This enabled the install process the necessary privilege's.
I had this issue when running an app within VS. All I had to do was run the program as Administrator once, then I could run from within VS.
To run as Administrator, just navigate to your debug folder in windows explorer. Right-click on the program and choose Run as administrator.
try below in web.config
<system.web>
<trust level="Full"/>
</system.web>
Rebuilding the solution worked for me

Problem with workflow on SharePoint email enabled document library

SO ... here is the scenario ... i have a workflow on a document library that copies a file to a windows directory ... this workflow is set to be started at the time when a new item is added to the document library ... so everything works fine when you are manually uploading files to the doc library ... but the problem occurs when we use emails to populate the doc library instead of the manual uploading of files.
When an email is received ... the workflow starts successfully and runs properly (i have kept workflow history entries to check every section of code is being executed or not) ... the workflow stops when the section where the file is being copied to the windows folder is reached.
I basically think this is a problem with the permissions or access issues. Because when we upload the file manually (i.e. from doc library > upload) everything works fine. But maybe there is some other permission set which is used while an email is received by the doc library ... i have tried by assigning permissions to "Everyone" on the windows folder ... but no luck...
Can someone let me know which windows user account is used when an email is received by a document library? (i think its the IIS default account - but isnt it included in Everyone?? )
One solution which i can devise in my mind is that for the file transfer to the windows folder i should use temporary impersonation for the specific code segment (which writes the doc library file to windows folder) but any suggestions are welcome.
P.S. I dont have access to the server right now so i can only devise approaches in my mind ... cant test them right nw... so it would be good to have all suggestions u have so that once i get the access i can try all stuff :D
This is a well known situation. The system does not know who sent the email so it cannot impersonate a user it has no knowledge about.
Depending on which version of SharePoint you are running, the workflow may not start at all or it may start under the account that published the workflow.
For details see this Microsoft Support Article.

Should the Network Service Account receive temp file permissions by default?

Recently I was working with generating a PDF from Crystal Reports through a webform. It was failing, which I determined to be caused by the permissions settings on the c:\windows\temp dir. I gave the Network Service account full access to this folder, which promptly fixed the issue. But is there a reason the Network Service account didn't have these permissions by default?
Rick Strahl asks this question here. It sounds like there shouldn't be any issues with doing this, but Rick wasn't clear on why the default is set that way.
Web Server is Windows Server 2003
These days, the default option will tend to be the more secure one. I don't think there's any other reason.
I've had the same issue as you, and in my environment just gave the permission and moved on.
This post suggests it is the fault of Crystal Reports, which is explicitly referencing %WINDIR%\Temp instead of using an API such as Path.GetTempPath(). In fact I have seen Path.GetTempPath() return %WINDIR%\Temp when running under the Network Service account on Windows 2003.
This post on creating temp files has comments that support using the windows temp folder.
An msdn article on using the Network Service account states that "if your ASP.NET application needs to use files or folders in other locations, you must specifically enable access" This tells me that the default restriction to the temp folder isn't because the temp folder was singled out, but that all other locations besides the IIS root folder are restricted by default.
%windows%\temp is not for general temp'ing and barfing around. It is crystal clear that Crystal Reports is abusing that directory. This happens a lot when developers are too lazy to boot up their machines with anything but an admin account.
Every user (including Network Service) has their own temp space, with full access rights, under Documents & Settings. Winners don't act like CR, and use their own temp spaces.
In short, there is nothing wrong with default permissions on win\temp. I believe it is simply meant for Windows' internal workings. (Then again, it would be much better for everyone concerned, if that directory never existed in the first place.)

Resources