.Net 6: WindowsIdentity.RunImpersonated failing with DirectoryNotFound error - asp.net-core-webapi

I am facing a problem when using WindowsIdentity.RunImpersonated.
I am running an ASP.NET Core 6 Web API as self-hosted (.exe) and using HTTP.Sys as host (instead of Kestrel). I am impersonating a user before making a HTTP call to another Web API from within this Web API.
Currently logged on user in this Windows 10 box is a domain user who is part of local admin group. The user I am impersonating is the same (currently logged on user).
When running the Web API by double clicking on it
Inside this impersonation, while calling HostBuilder.Build(), the call is failing with an error
System.IO.DirectoryNotFoundException
The path in the exception is of the folder from where this Web API process is running. I checked in the .NET Core code and it is failing in
new PhysicalFileProvider(_hostingEnvironment.ContentRootPath);
When running web API by right click on exe and "Run as admin"
No issues, HTTP call goes to other Web API and proper response is returned.
Even though I am logged on in this Windows machine with Admin privileges, still I have to run the Web API process explicitly as "Run as Admin" to make things work. This is what I am not getting.
Could someone please help here?

Related

Blazor Webassembly asp.net hosted with Microsoft Azure AD authentication

I found a lot number of examples how o do this.
https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/hosted-with-azure-active-directory?view=aspnetcore-6.0
And it works fine when I run it locally in debug.
Everything is fine, until I want to publish the application up to an Azure APP Service.
I create an App Service and connect the server registration to it
I add on the client registration the URL of the APP Service https://xxxxx.azurewebsites.net/authentication/login-callback
In Visual Studio 2022 I publish the server application up to the App Service
To my surprise, the application does not work from the published site...
I get the response:
Sign in
Sorry, but we’re having trouble signing you in.
AADSTS700054: response_type 'id_token' is not enabled for the application.
I can not find an example that go all the way to a published APP service...
So what is wrong in my thinking here?
You need to register the app in Azure AD.
Your error message is: "'id_token' is not enabled for the application"
To fix this under Advanced Settings, Implicit grant check the box "ID tokens".

How to make local IIS use a different Azure Active Directory for access to resources

Here's the situation: I have an account in the azure active directory of my company with several subscriptions. I am building an ASP.NET Framework application for a client. This application is going to be hosted in their own azure environment, so to set this up, they added my email address to their azure active directory. Now in the azure portal I can use the button "change active directory" to either view my company's resources or my client's.
I set up a keyvault in my client's azure environment and I added keyvault as connected service to my application using these instructions. My application is running locally in local IIS, so I set up the application pool to use my user account so it has access to my azure subscriptions.
The issue here is that I still get an error when I try to run the application. The ysod says that azure gives a 401 response when trying to access the keyvault. I see that it's trying to use the guid that is associated with my company's azure active directory (I don't know what the name of this guid is). Obviously, I can't access resources from my client's azure environment with my company's azure active directory.
As an attempt to get more information, I built a small console application and used the same procedure to add keyvault as a connected service, since the internet says that the console application gives more details than the ASP.NET application. However, when I run my console application, I don't get any errors at all and I can access my client's keyvault just fine.
This makes me believe that there is some setting in my user account or IIS that I need to change to make this work, but I can't find what it is.
How can I make my ASP.NET Framework application, running locally in IIS, access a keyvault as connected service in my client's azure environment?
This should work, try to follow this to re-login your user account in VS and make sure you have modified your ASP.NET Framework project.
If it still not work, you could ask your client to create a work account for you in their Azure AD tenant and add it to the keyvault access policy, then use the account to login VS and test.

Unable to connect to database with .NET Core 3.1 File System Publish to IIS

Question: How do I properly setup the database connection when using the File System method to publish an ASP .NET Core 3.1 Web-Api to IIS running on Windows 10? I believe I have added all of the correct Windows features for IIS because it runs and I am running VS 2019 Community in Admin mode.
This is my first time deploying a .NET Core 3.1 Web-API to IIS via the Publish method. I am able to successfully publish the web application to IIS. But it appears that something is wrong with the database configuration because when I try submit a login POST via Postman, I am getting an error message from the API error handling middleware that the credentials are invalid, which effectively means that the Web-API cannot connect to the database. As a test, when I try running in debug with IIS Express and change the connection string, I get the same error. Note: the IIS server logs do not contain any relevant output to confirm this, but I am pretty sure this is the problem.
In searching online, I am struggling to find a simple and direct walk through on how to publish a Web-API with a database connection. I suspect the problem is in the Connected Services section of the publish profile. I had to battle through some build errors that related to missing packages, and this item:
https://obscureproblemsandgotchas.com/development/c/dotnet-core-ef-migration-not-working/
Once I applied this change, the database data context strings could be read from the Publish Settings section of the publish profile, which reads the connection strings from the appsettings.json file. Though, I had to modify that string to remove an escape '' from the actual json value so that the test connection would succeed.
Any help is greatly appreciated.
You could set the connection string at the time of deploy from the visual studio as shown below :
Make sure you installed the .NET Core Hosting Bundle and .NET Core Runtime.
after doing all these things set the application pool identity to the administrator:
Open iis manager, select your application pool.
Click on advance setting from the action pane.
Under Process Model, click on the “Identity” value and select “Custom account”.
enter your domain user name and password which user has to access to the database and click ok to apply the changes.
after applying changes select the application pool and click on the “Recycle”.
restart your site.
Please refer below link for more detail:
https://forums.iis.net/post/2159167.aspx

In ASP.NET, under which credentials does the code run?

1) I want to know suppose we are using an ASP.NET web application in debug mode in VS, then, the code runs under which user account?
2) I also want to know, suppose we publish this to the IIS and then, set it up to use WBA/FBA, then, the username/password of logged in user is used to authenticate user to the ASP.NET site, however, the code (SQL query, etc) runs under credentials of apppool account. Further, which credential is used to access resources on server like files? What is your view on this point?
1) I want to know suppose we are using an ASP.NET web application in
debug mode in VS, then, the code runs under which user account?
This is depending on the hosting. VS provides 4 ways to host & debug a web application : VS Dev Server (VS 2012), IIS Express, Local IIS and Custom Host (VS 2013). Devs servers generally runs under your -Administrator- account, and may not be suitable to test security. Working directly with IIS as your development web server lets you work in an environment closer to that of an IIS production web server.
This is configured in the Web Tab in your web project properties.
2) I also want to know, suppose we publish this to the IIS and then,
set it up to use WBA/FBA, then, the username/password of logged in
user is used to authenticate user to the ASP.NET site, however, the
code runs under credentials of apppool account. What is your view on
this point?
Not very clear, but I think your undestanding of IIS security may not be correct. There is only one application pool per web site which runs under a specific account (by default apppool account, but it could be Network Service or Local System). When a user logs in, absolutely nothing is changed in this process. The user is just connected using an authentication provider : Windows Authentatication or Forms Authentication are 2 common providers. User identity is kept in http context, which allow you to use authorization rules later. So every code block always run under the same account (unless you enable delegation but that's another story).
I higly suggest you to read this complete introduction on asp.net security.

Run console application (.exe) from within ASP.NET application (IIS 7,5)

I have an ASP.NET application on Windows 2008 R2 (.NET Framework 4.0, IIS 7.5) and I want to run a console application when I click a button on a web page. Here is the code:
protected void btnUpdate_Click(object sender, EventArgs e)
{
string fileLocation = #"D:\DTDocs\App_Code\LoadDTDocsXML.exe";
ProcessStartInfo oStartInfo = new ProcessStartInfo();
oStartInfo.FileName = fileLocation;
oStartInfo.UseShellExecute = false;
Process.Start(oStartInfo);
}
When I run ASP.NET application from within Visual Studio 2010 (with its internal IIS), the console application run Ok. But when I run the ASP.NET application outside the VS 2010, I haven't an error but the console application doesn't make his job (it must create an xml file on the disk).
I think the problem is the configuration of IIS 7.5, I don't know exact to which account I must give access rights to the folders involved in my console application.
In IIS 7.5, I set Physical Path Credential for Specific User = my windows account, but that not solve the problem.
Thanks.
Just to add to the other 2 answers - Do you really need to run an exe from your webserver?
I've had to do it in the past and it's almost always the option of last resort - It weakens your security considerably (Now all someone has to do to run executables on your system is find a single flaw in your code) and has a whole host of other problems (the webserver isn't "logged on" to the server so it doesn't have a desktop, impersonation is a real pain in the a$$ to get working properly (assuming you're going to run the executable with different permissions to the webserver), etc.
If there's any other way to accomplish your goal, it'll almost certainly be simpler.
An option we went for was to have a new app with a WCF endpoint that the webserver can communicate with. So, when someone pushes the button, the WS call's our app via WCF and tells it to run various commands. This way, you've got:
Clean seperation between web and console code.
A dodgy console app won't take down the webserver & vice-versa
If the console app is long-running, this allows you to stagger your releases for website/console app so that you don't kill the app mid-execution just because you need up upodate some CSS and publish.
Huge security benefits - web server can't run executables even if compromised.
The WCF app will be able to closely examine requests to decide if they're valid before execution.
Be aware that however you do it, if someone malicious works out what's going on and can kick off the process, they could probably DoS you with almost zero effort - Make sure that this method is locked down TIGHT.
Edit: having read your comments above, I think you're hitting the "desktop" issue. When launching an executable from the server, the app will never be visible to the logged on user as the logged on user's desktop isn't accessible from IIS and vice-versa. This is very similar to the issue of having a GUI on a windows service.
This may also be of interest.
the first problem I see is security/file access. when running from within VS the server and client are the same machine under your credentials. when run in testing/production environment the server and client are physically different machines and IIS will run the website under restricted permissions. therefore there is a very good chance that IIS cannot access the file at D:... because of security.
the next issue is running a console app from the website. console is another form of UI just like html and a WPF. personally I wouldn't execute the console from the web (unless there was no other choice). I would integrate the API into the web application. 2 UIs sharing the same logic.
ASP.NET Dev Server runs under credentials of current user (it's you).
IIS 7.5 runs ASP.NET applications under user specified in application pool settings -- usually ApplicationPoolIdentity (to which you can refer as user "IIS AppPool\[ApplicationPoolName]", when configuring file permissions). You can also change it to "Network Service" (Default value in IIS 7.0).
Please check, which identity is configured for your application pool, and give this user required permissions.

Resources