Hi I am trying to create an installer that installs a published website and grants access to the App_Data folder for the ASPNET user.
I have used the Web Deployment Project to install the published website but cannot figure out how to set the App_Data folder permissions for the ASPNET user.
At the moment I have to manually set the folder permissions in the security tab of the folder (everything except full control) after installing the website.
Does anyone know if there's a way of doing this in the installer?
When we deploy ASP.NET application on IIS, the accounts that runs your application might be "ASPNET" or "NETWORK SERVICE" basing on IIS version.
You can add the access control list (ACL) entries to the file in custom action of Web Setup project. For example, adds an ACL entry on the specified file for the specified account:
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question.
Thanks for the pointer. I'm new to .Net and am still getting use to the number of provided classes.
Its a bit more complicated than I wanted but it works well. I use a custom action DLL which inherits from the Installer class and then use the DirectorySecurity examples from MSDN to set the App_Data folder permissions for the ASPNET user.
I'm currently trying to write code that will find out what user to use as the ASPNET user does not exist on Vista machines (unless .Net 1.1 has been installed).
I'll post the code to do this when I figure it out.
He's the code I settled on. The AddDirectorySecurity and RemoveDirectorySecurity functions are very similar to the examples on MSDN. This code gives the ASPNET or NETWORK SERVICE account all permissions except full control to the App_Data folder.
I set the CustomActionData in the installer to /TheInstallFolder="[TARGETDIR]\"
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Security.AccessControl;
using System.Windows.Forms;
using System.IO;
namespace CustomInstallAction
{
[RunInstaller(true)]
public partial class MyCustomInstaller : Installer
{
public MyCustomInstaller()
{
InitializeComponent();
}
/// <summary>
/// When installing set the permissions on the App_Data directory
/// </summary>
/// <param name="stateSaver"></param>
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
Boolean addedSecurity = false;
string directoryName = string.Empty;
try
{
directoryName = Path.Combine(this.Context.Parameters["TheInstallFolder"].ToString(), "App_Data");
}
catch
{
//TODO log these issues
}
if (directoryName.Length > 0)
{
// Try add access to the App_Data folder for the ASPNET user
try
{
// Add the access control entry to the directory.
AddDirectorySecurity(directoryName, System.Environment.MachineName + @"\ASPNET", FileSystemRights.Modify, AccessControlType.Allow);
AddDirectorySecurity(directoryName, System.Environment.MachineName + @"\ASPNET", FileSystemRights.Write, AccessControlType.Allow);
RemoveDirectorySecurity(directoryName, System.Environment.MachineName + @"\ASPNET", FileSystemRights.Delete, AccessControlType.Deny);
addedSecurity = true;
}
catch (Exception ex)
{
//TODO log these issues
//MessageBox.Show(System.Environment.MachineName + @"\ASPNET" + ex.ToString());
}
// If adding the ASPNET user failed try the NetworkService user
if (!addedSecurity)
{
try
{
// Add the access control entry to the directory.
AddDirectorySecurity(directoryName, @"NT AUTHORITY\NETWORK SERVICE", FileSystemRights.Modify, AccessControlType.Allow);
AddDirectorySecurity(directoryName, @"NT AUTHORITY\NETWORK SERVICE", FileSystemRights.Write, AccessControlType.Allow);
RemoveDirectorySecurity(directoryName, @"NT AUTHORITY\NETWORK SERVICE", FileSystemRights.Delete, AccessControlType.Deny);
addedSecurity = true;
}
catch (Exception ex)
{
//TODO log these issues
//MessageBox.Show("NT AUTHORITY\\LOCAL SERVICE" + ex.ToString());
}
}
}
}
public override void Commit(System.Collections.IDictionary savedState)
{
base.Commit(savedState);
}
public override void Rollback(System.Collections.IDictionary savedState)
{
base.Rollback(savedState);
}
public override void Uninstall(System.Collections.IDictionary savedState)
{
base.Uninstall(savedState);
}
public static void Main()
{
}
/// <summary>
/// Adds an ACL entry on the specified directory for the specified account.
/// </summary>
/// <param name="dirName">Folder path to add the permissions to</param>
/// <param name="Account"></param>
/// <param name="Rights"></param>
/// <param name="ControlType"></param>
private static void AddDirectorySecurity(string folderName, string account, FileSystemRights rights, AccessControlType controlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(folderName);
// Get a DirectorySecurity object that represents the current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(account, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, controlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
/// <summary>
/// Removes an ACL entry on the specified directory for the specified account.
/// </summary>
/// <param name="FileName"></param>
/// <param name="Account"></param>
/// <param name="Rights"></param>
/// <param name="ControlType"></param>
public static void RemoveDirectorySecurity(string folderName, string account, FileSystemRights rights, AccessControlType controlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(folderName);
// Get a DirectorySecurity object that represents the current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.RemoveAccessRule(new FileSystemAccessRule(account, rights, controlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
}
}
Marked as answer by dburton on Aug 22, 2008 02:59 PM
Works great but wow that is a lot of code to add simple write ability to the folder that holds your database file. I don't understand why this is not easier. Did MS not think Access databases would be in that folder on deploy?
dburton
0 Points
4 Posts
Automatically give the ASPNET user access to the App_Data Folder
Aug 06, 2008 08:04 AM|LINK
Hi I am trying to create an installer that installs a published website and grants access to the App_Data folder for the ASPNET user.
I have used the Web Deployment Project to install the published website but cannot figure out how to set the App_Data folder permissions for the ASPNET user.
At the moment I have to manually set the folder permissions in the security tab of the folder (everything except full control) after installing the website.
Does anyone know if there's a way of doing this in the installer?
WebDeploymentSetup.msi "Web Deployment Project" web deploy Web Deployment Project web deployment projects build configuration ASP.NET web development ASPNET App_Data
Thomas Sun –...
All-Star
64969 Points
5621 Posts
Re: Automatically give the ASPNET user access to the App_Data Folder
Aug 12, 2008 03:12 AM|LINK
Hi,
When we deploy ASP.NET application on IIS, the accounts that runs your application might be "ASPNET" or "NETWORK SERVICE" basing on IIS version.
You can add the access control list (ACL) entries to the file in custom action of Web Setup project. For example, adds an ACL entry on the specified file for the specified account:
public static void AddFileSecurity(string fileName, string account,
FileSystemRights rights, AccessControlType controlType)
{
// Get a FileSecurity object that represents the
// current security settings.
FileSecurity fSecurity = File.GetAccessControl(fileName);
// Add the FileSystemAccessRule to the security settings.
fSecurity.AddAccessRule(new FileSystemAccessRule(account,
rights, controlType));
// Set the new access settings.
File.SetAccessControl(fileName, fSecurity);
}
For more information, see http://msdn.microsoft.com/en-us/library/system.io.file.setaccesscontrol.aspx
I look forward to receiving your test results.
Microsoft Online Community Support
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question.
dburton
0 Points
4 Posts
Re: Automatically give the ASPNET user access to the App_Data Folder
Aug 13, 2008 10:59 AM|LINK
Thanks for the pointer. I'm new to .Net and am still getting use to the number of provided classes.
Its a bit more complicated than I wanted but it works well. I use a custom action DLL which inherits from the Installer class and then use the DirectorySecurity examples from MSDN to set the App_Data folder permissions for the ASPNET user.
I'm currently trying to write code that will find out what user to use as the ASPNET user does not exist on Vista machines (unless .Net 1.1 has been installed).
I'll post the code to do this when I figure it out.
Thanks again!!!
dburton
0 Points
4 Posts
Re: Automatically give the ASPNET user access to the App_Data Folder
Aug 22, 2008 02:58 PM|LINK
Hi,
He's the code I settled on. The AddDirectorySecurity and RemoveDirectorySecurity functions are very similar to the examples on MSDN. This code gives the ASPNET or NETWORK SERVICE account all permissions except full control to the App_Data folder.
I set the CustomActionData in the installer to /TheInstallFolder="[TARGETDIR]\"
using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration.Install; using System.Security.AccessControl; using System.Windows.Forms; using System.IO; namespace CustomInstallAction { [RunInstaller(true)] public partial class MyCustomInstaller : Installer { public MyCustomInstaller() { InitializeComponent(); } /// <summary> /// When installing set the permissions on the App_Data directory /// </summary> /// <param name="stateSaver"></param> public override void Install(System.Collections.IDictionary stateSaver) { base.Install(stateSaver); Boolean addedSecurity = false; string directoryName = string.Empty; try { directoryName = Path.Combine(this.Context.Parameters["TheInstallFolder"].ToString(), "App_Data"); } catch { //TODO log these issues } if (directoryName.Length > 0) { // Try add access to the App_Data folder for the ASPNET user try { // Add the access control entry to the directory. AddDirectorySecurity(directoryName, System.Environment.MachineName + @"\ASPNET", FileSystemRights.Modify, AccessControlType.Allow); AddDirectorySecurity(directoryName, System.Environment.MachineName + @"\ASPNET", FileSystemRights.Write, AccessControlType.Allow); RemoveDirectorySecurity(directoryName, System.Environment.MachineName + @"\ASPNET", FileSystemRights.Delete, AccessControlType.Deny); addedSecurity = true; } catch (Exception ex) { //TODO log these issues //MessageBox.Show(System.Environment.MachineName + @"\ASPNET" + ex.ToString()); } // If adding the ASPNET user failed try the NetworkService user if (!addedSecurity) { try { // Add the access control entry to the directory. AddDirectorySecurity(directoryName, @"NT AUTHORITY\NETWORK SERVICE", FileSystemRights.Modify, AccessControlType.Allow); AddDirectorySecurity(directoryName, @"NT AUTHORITY\NETWORK SERVICE", FileSystemRights.Write, AccessControlType.Allow); RemoveDirectorySecurity(directoryName, @"NT AUTHORITY\NETWORK SERVICE", FileSystemRights.Delete, AccessControlType.Deny); addedSecurity = true; } catch (Exception ex) { //TODO log these issues //MessageBox.Show("NT AUTHORITY\\LOCAL SERVICE" + ex.ToString()); } } } } public override void Commit(System.Collections.IDictionary savedState) { base.Commit(savedState); } public override void Rollback(System.Collections.IDictionary savedState) { base.Rollback(savedState); } public override void Uninstall(System.Collections.IDictionary savedState) { base.Uninstall(savedState); } public static void Main() { } /// <summary> /// Adds an ACL entry on the specified directory for the specified account. /// </summary> /// <param name="dirName">Folder path to add the permissions to</param> /// <param name="Account"></param> /// <param name="Rights"></param> /// <param name="ControlType"></param> private static void AddDirectorySecurity(string folderName, string account, FileSystemRights rights, AccessControlType controlType) { // Create a new DirectoryInfo object. DirectoryInfo dInfo = new DirectoryInfo(folderName); // Get a DirectorySecurity object that represents the current security settings. DirectorySecurity dSecurity = dInfo.GetAccessControl(); // Add the FileSystemAccessRule to the security settings. dSecurity.AddAccessRule(new FileSystemAccessRule(account, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, controlType)); // Set the new access settings. dInfo.SetAccessControl(dSecurity); } /// <summary> /// Removes an ACL entry on the specified directory for the specified account. /// </summary> /// <param name="FileName"></param> /// <param name="Account"></param> /// <param name="Rights"></param> /// <param name="ControlType"></param> public static void RemoveDirectorySecurity(string folderName, string account, FileSystemRights rights, AccessControlType controlType) { // Create a new DirectoryInfo object. DirectoryInfo dInfo = new DirectoryInfo(folderName); // Get a DirectorySecurity object that represents the current security settings. DirectorySecurity dSecurity = dInfo.GetAccessControl(); // Add the FileSystemAccessRule to the security settings. dSecurity.RemoveAccessRule(new FileSystemAccessRule(account, rights, controlType)); // Set the new access settings. dInfo.SetAccessControl(dSecurity); } } }rockbeans
Member
12 Points
32 Posts
Re: Automatically give the ASPNET user access to the App_Data Folder
Feb 01, 2010 08:17 PM|LINK
Works great but wow that is a lot of code to add simple write ability to the folder that holds your database file. I don't understand why this is not easier. Did MS not think Access databases would be in that folder on deploy?
dburton
0 Points
4 Posts
Re: Automatically give the ASPNET user access to the App_Data Folder
Feb 02, 2010 07:43 AM|LINK
You may also need to use
string networkService = new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null).Translate(typeof(NTAccount)).Value.ToString();
instead of the hardcoded "NETWORK SERVICE" string if installing on a non english server
rockbeans
Member
12 Points
32 Posts
Re: Automatically give the ASPNET user access to the App_Data Folder
Feb 02, 2010 02:31 PM|LINK
Works Great.
networkService = NT AUTHORITY\NETWORK SERVICE
THANKS!