Security settings to start a windows service in a ASP.net web app - asp.net

I have a bit of code in an internal ASP.net application that we use to start automatic services should they be stopped on the server that the web app is running on. The only problem is that it doesn't seem to start the service when its run on the server. It does so fine when its run on my desktop locally though so I'm guessing I have to give certain security settings to the the ASP.net user?
Here's my code:
protected void StartService(object sender, EventArgs e)
{
LinkButton serviceButton = (LinkButton)sender;
string name = serviceButton.ID;
ManagementPath path = new ManagementPath();
path.Server = System.Environment.MachineName;
path.NamespacePath = #"root\CIMV2";
path.RelativePath = "Win32_service.Name='" + name + "'";
ManagementObject service = new ManagementObject(path);
ManagementBaseObject temp = service.InvokeMethod("StartService", null, null);
Thread.Sleep(100);
GetStoppedServices();
}
Anyone have any ideas on how to get this to work?
Edit: For clarification the web app is run on the same server as the server that I want to start services on.
Edit 2: Had a brainwave and tried to use this code instead.. no dice.
ProcessInfo = new ProcessStartInfo("cmd.exe", "/C net start " + name);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = false;
Process = Process.Start(ProcessInfo);
Process.Close();

Rather than using the System.Management objects for controlling services, look into the ServiceController class. All the methods for start/stop/pause are available and in a much more structured manner.
You may still encounter permission issues, though. The executing account for your web app will require permissions to control the target service you wish to affect.
Depending on your platform (which version of Win Serv), different accounts will execute for anonymous requests for your web application. Verify which accounts come into play (or if you have authenticated requests, you know your user) and determine their privileges against your Windows service.

Could be an access rights issue. When you run the application locally (through Visual Studio and the built-in Cassini web server) I think you're running it as yourself, so it makes sense that it would work.
When you run the application through IIS (on the server), its running as whatever user is specified in the application pool. (I think its "Network Service" by default). Check which user it is in IIS and try giving that user permission to start your service.
What version of IIS are you running? If its a Win 2K3 server, I'm guessing 6.0.
Information on configuring the application pool:
IIS 7.0
IIS 6.0
EDIT: You can use SubInACL.exe (a microsoft tool) to configure service permissions:
So let's say you have user "Johnny" and you want Johnny to be able to stop and start the World Wide Web Publishing service. Simply run the following subinacl.exe command:
subinacl /service W3SVC /GRANT=YOURDOMAIN\Johnny=TO
Obviously you will want to replace YOURDOMAIN with the name of your domain. The TO at the end are the identifiers that tell subinacl which actions you actually want grant to Johnny. T is used for "Start Service" and O is for "Stop Service".
For more information, check out Ingmar's blog post about it.

For Windows 7, Windows Server 2008, Windows Server 2008 R2, Windows Vista
Open IIS Manager.(From start->run-> type inetmgr and press enter)
In the Connections pane, expand the server node and click Application Pools.
On the Application Pools page, select the application pool for which you want to specify an identity, and then click Advanced Settings in the Actions pane.
For the Identity property, click the ... button to open the Application Pool Identity dialog box.
If you want to use a built-in account, select the Built-in account option and select an account from the list. Select Local System from the list
If you want to use a custom identity, select the Custom account option and click Set to open the Set Credentials dialog box. Then type the custom account name in the User name text box, type a password in the Password text box, retype the password in the Confirm password text box, and then click OK.
Click OK to dismiss the Application Pool Identity dialog box.
Right click on the application pull and then stop and again click on start

Related

The ASP.NET ETW provider on a win7 PC is missing

I am writing an ETW consumer to listen for ASP.NET events. I have the sample code below working nicely on a Windows 2008 server where it can see the ASP.NET provider. The problem that I am running into is that on my Win7 (64) PC, I do not see the ASP.NET provider so this code shows all the events as “unhandled”.
I have made sure the tracing feature is installed and the applicationhost.config file has the respective values in it.
When I do a logman –query providers, I do not see the
ASP.NET AFF081FE-0247-4275-9C4E-021F3DC1DA35 provider on the PC, but I see this on the Win2008 server that I am testing on.
How can I do one of the two items below:
Add this as a provider to my Win7 PC?
OR
Have the code able to handle this message and provide the manifest in my code. When I set “AFF081FE-0247-4275-9C4E-021F3DC1DA35” as a provider, I do get events but they are from unknown provider. So I am guessing the manifest content is missing.
My sample code is below
static void Test3()
{
var sessionName = "ASPNETMonitorSession";
using (var session = new TraceEventSession(sessionName, null))
{
Console.WriteLine("Starting Test1");
session.StopOnDispose = true;
Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
session.Dispose();
};
using (var source = new ETWTraceEventSource(sessionName, TraceEventSourceType.Session))
{
Action<TraceEvent> action = delegate(TraceEvent data)
{
Console.WriteLine("GOT EVENT: " + data.ToString());
};
var registeredParser = new RegisteredTraceEventParser(source);
registeredParser.All += action;
source.UnhandledEvents += delegate(TraceEvent data)
{
if ((int)data.ID != 0xFFFE)
Console.WriteLine("GOT UNHANDLED EVENT: " + data.Dump());
};
session.EnableProvider(new Guid("AFF081FE-0247-4275-9C4E-021F3DC1DA35"));
Console.WriteLine("Starting Listening for events");
source.Process();
}
}
Console.WriteLine("Done");
return;
}
The reason why ASP.NET tracing isn't available in your local machine is because it is not installed. If you look at the perfview help it gives you instructions as to how to enable it.
FYI perfview uses TracEevent to capture traces.
Here it is
ASP.NET Events
ASP.NET has a set of events that are sent when each
request is process. PerfView has a special view that you can open
when ASP.NET events are turned on. By default PerfView turns on
ASP.NET events, however, you must also have selected the 'Tracing'
option when ASP.NET was installed for these events to work. Thus if
you are not seeing ASP.NET events you are running an ASP.NET scenario
this is one likely reason why you are not getting data.
To turn on ASP.NET Tracing
The easiest way to turn on tracing is with the DISM tool that comes
with the operating system. Run the following command from an
elevated command prompt
DISM /online /Enable-Feature /FeatureName:IIS-HttpTracing
Note that this command will restart the web service (so that it takes effect),
which may cause complications if you ASP.NET service handles long
(many second) requests. This will either force DISM to delay (for a
reboot) or abort the outstanding requests. Thus you may wish to
schedule this with other server maintenance. Once this configuration
is done on a particular machine, it persists. You can also do
this configuration by hand using a GUI interface. You first need to
get to the dialog for configuring windows software. This differs
depending on whether you are on a Client or Server version of the
operating system.
On Client - Start -> Control Panel -> Programs -> Programs and
Features -> Turn Windows features on or off
-> Internet Information Services -> World Wide Web Services -> Health and Diagnostics -> Tracing On Server - Start -> Computer -> Right
Click -> Manage Roles -> Web Server (IIS) -> Roll Services Add Role
Services Health and Diagnostics -> Tracing
Hope this helps.

webbrowser control in windows form not log in

Windows form has webbrowser control which logins to pages.
when i click the exe on server it log ins.however when i run the exe from asp.net page using process, logins fails. I think webbrowser not use the cookies while running under process of asp.net page.
System.Diagnostics.Process process1 = new System.Diagnostics.Process();
process1.StartInfo.WorkingDirectory = #"C:\ceza\";
process1.StartInfo.FileName = #"WindowsCezaPuani.exe";
process1.StartInfo.Arguments = args;
process1.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
process1.StartInfo.CreateNoWindow = false;
process1.Start();
How can i overcome this problem ? or the problem raising from webbrowser cookies ?
Thanks for any help.
It should be caused by different identity used. When starting the process from asp.net pages, the process is running under the application pool identity by default.
You can try to set the application pool identity to your computer logon account.
Follow the link below for the steps to set identity of your application pool.
http://technet.microsoft.com/en-us/library/cc771170%28v=WS.10%29.aspx

how to get current windows user in wcf

I already tried link from stackoverflow
I have a silverlight client and wcf service. The application has 3 authentication modes
Active Directory
Windows Pass Through
Proprietary - I don't have a problem with this one obviously.
(I really don't know what is the difference between active directory and Window Pass Through. I just use the same code for both, except for windows pass through I get the current user and for AD the app prompts for username password)
.
private string GetCurrentUser()
{
try
{
string result = WindowsIdentity.GetCurrent().Name;
WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
result = wp.Identity.Name;
if (result.Contains(#"\"))
{
int position = result.LastIndexOf(#"\") + 1;
result = result.Substring(position);
}
return result;
}
catch (Exception ex)
{
return "";
}
}
Both WindowsIdentity and WindowsPrincipal returns 'DefaultAppPool' or whatever the AppPool the current thread runs. Even Environment.UserName returns the same.
When I turn on <identity impersonate ="true"/> in web.config the silverlight client fails to connect to wcf. It gets a 'Not Found' error. So, I need to keep <identity impersonate ="false"/>
All I need is the current logged on user, I didn't know that it's this difficult.
I changed the identity on the Application Pool to my own user account and it worked.
Open IIS Console
Select Application Pools.
Select the AppPool (in my case it was DefaultAppPool).
On the right pane click Advanced Settings.
There are different categories of settings like General, CPU, Process Model.
Under Process Model -> Identity click the right side input box, a button shows up, click it.
It opens a dialog box with 2 radio buttons (Built-in account and Custom account).
Select custom account and hit Set.
Set Credentials dialog box opens.
Enter your credentials and hit okay. You may have to enter [domain][user name]
Hit Ok to all the dialog boxes to close everything.
Now test your app, WindowsIdentity.GetCurrent().Name should return the username associated with the Application Pool.

How to run external exe under specific account from asp.net web service?

Bellow is my code from asp.net service which is trying to run some external exe. It works fine from my Visual Studio on win 7, but fails on my server (server 2008).
Myapp.exe reports back eror that account under which is runned doesn't have sufficiet priviliges.
List<ProcInfo> allProcesses = new List<ProcInfo>();
ProcessStartInfo pInfo = new ProcessStartInfo();
pInfo.FileName = binPath + #"\myApp.exe";
pInfo.WindowStyle = ProcessWindowStyle.Hidden;
pInfo.CreateNoWindow = true;
pInfo.UseShellExecute = false;
pInfo.RedirectStandardOutput = true;
string exitMsg = "";
int exitCode = 1;
try
{
using (Process proc = Process.Start(pInfo))
{
exitMsg = proc.StandardOutput.ReadToEnd();
proc.WaitForExit(1000);
exitCode = proc.ExitCode;
}
}
Resource pool on the server runs under account with sufficient priviliges and I also tried to use same account in code to start service with those same credentials and still nothing.
I have been told that account under which asp.net worker thread runs impose some additional limitations. So even if resource pool runs under appropriate account, you still won't have sufficient priviligies.
I also found something about using pInvoke and win32 api calls as the only way to run external code from asp.net service. But I don't have any win32 api knowlege nor did I found exples of this.
I would be very grateful for any tip/example how to run external exe under specified account from asp.net service.
If the account the worker process is runnning under lacks sufficient privelages then you have a few options.
You can either use impersonation in your code:
WindowsIdentity.Impersonate Method
Or configure IIS to run the application under a user account with the required privileges.
Here is an article which explains different methods of impersonation security:
Understanding ASP.NET Impersonation Security
If you do not feel confident implementing the user impersonation code yourself, here is a link to a codeproject article:
A small C# Class for impersonating a User

How to find out which account my ASP.NET code is running under?

I am getting an 'Access to the path is denied" error message when running in debug mode. I have tried granting permissions to {MACHINENAME}\ASPNET and to NETWORK SERVICE but this hasn't made any difference. I have also tried < impersonate = true /> using an admin account, this also made no difference. So how do I establish exactly which account is being used?
To find out which NT account your app is running under at any given time, do something like (in VB.NET):
Dim User = System.Security.Principal.WindowsIdentity.GetCurrent.User
Dim UserName = User.Translate(GetType(System.Security.Principal.NTAccount)).Value
When using ASP.NET, this account will match the identity of the application pool, which you configure using IIS Manager. Note that the anonymous IIS user isn't much involved with ASP.NET requests.
C# Code for the vb.net answer
var user = System.Security.Principal.WindowsIdentity.GetCurrent().User;
var userName = user.Translate(typeof (System.Security.Principal.NTAccount));
You could use this code:
C#
Response.Write("Windows Account which runs ASP.NET is: "
+ Environment.Username);
VB.NET
Response.Write("Windows Account which runs ASP.NET is: " _
& Environment.Username)
If you run your application in Visual Studio on your PC (localhost) you'll get your user name. If you deploy ASP.NET web application on IIS, you will probably get the NETWORK SERVICE account, because that is default user running IIS 6.0 (ASPNET on Windows Server 2000's IIS 5.0).
Environment.UserName returns the thread's currently logged-on user. Page.User returns the name that ASP.NET verifies through Authentication and this user in most cases is independent of the Windows logon that is running the current thread. For anonymous requests Page.User is blank, while Environment.User will be NETWORK SERVICE.
As mdb correctly points out in a comment to this answer, Environment.Username will simply return the USERNAME environment variable, which is set on process creation and not updated in case of impersonation and such.
strint t=System.Web.Security.Membership.GetUser().UserName.ToString();

Resources