Reputation: 951
I'm very new to Windows environment, I've struggle a lot making my c# API work on IIS. I only managed to do a GET on my Web API.
When I try to do a POST, I get this:
{"Message": "An error has occurred.",
"ExceptionMessage": "Access to the path 'C:\\Path\\To\\API' is denied.",
"ExceptionType": "System.UnauthorizedAccessException",
"StackTrace": " at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.Directory.InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, Boolean checkHost)\r\n at System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean checkHost)\r\n at MiningAPI.Controllers.ValuesController.Post(HttpRequestMessage request) in C:\\Users\\Tavernier\\Desktop\\MiningReport\\MiningAPI\\MiningAPI\\Controllers\\ValuesController.cs:line 90\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"}
Permissions on IUSRS
and IIS_IUSRS
are fully allowed to read files on the Web API folder.
I'm on Windows 10, running IIS-10
UPDATE:
POST was working when I launched the Web API through Visual Studio. (localhost:port, now 192.168.1.30:port)
I tried to move my folder to D:
, added NETWORK SERVICE
to the permissions.
Upvotes: 1
Views: 4689
Reputation: 2418
The user being used depends on your application pool. If no identity has been specific within the IIS Application Pool used by your application, then the default will be "IIS AppPool\<AppPool Name>" (without quotes).
see https://www.iis.net/learn/manage/configuring-security/application-pool-identities for more information.
I would recommend that any folders the app pool user needs to write to, is granted permission to explicitly. It would be unwise to allow the app pool user full write access especially to code directories, as that could lead to modification of sources if present.
Here is some code that will do a basic check for permissions. It doesn't go off and find all the user groups that the user belongs to, so wouldn't work in an extended situation. However, with application pools using the default identity, they should get either the app pool name or BUILTIN\Users
Import-Module WebAdministration
$websites = (Get-ChildItem IIS:\Sites)
foreach ($website in $websites)
{
$appPool = (Get-Item IIS:\AppPools\$($website.applicationPool))
Write-Output "Found $($website.name) with $($appPool.name) in mode $($appPool.processModel.identityType)";
$folder = [System.Environment]::ExpandEnvironmentVariables($website.physicalPath);
if ($appPool.processModel.identityType -eq 3)
{
$user = $appPool.processModel.userName;
Write-Output "Using explicit username '$user'";
} else {
$user = "IIS AppPool\" + $appPool.name;
Write-Output "Using application pool name '$user'";
}
$permission = (Get-Acl $Folder).Access | ?{$_.IdentityReference -match $User -or $_.IdentityReference -match "BUILTIN\\Users" } | Select IdentityReference,FileSystemRights
If ($permission){
$permission | % {Write-Host "User $($_.IdentityReference) has '$($_.FileSystemRights)' rights on folder $folder"}
} Else {
Write-Host "$User Doesn't have any permission on $Folder"
}
}
On my system this gives the following output
Found Default Web Site with DefaultAppPool in mode ApplicationPoolIdentity
Using application pool name 'IIS AppPool\DefaultAppPool'
User BUILTIN\Users has 'ReadAndExecute, Synchronize' rights on folder C:\inetpub\wwwroot
User BUILTIN\Users has '-1610612736' rights on folder C:\inetpub\wwwroot
Upvotes: 3
Reputation: 44620
Your WebAPI tries to access the path C:\\Path\\To\\API
. It runs on behalf of IIS user that doesn't have access to it. Try to grant access to NETWORK_SERVICE
user as well. Then perform iisreset
from CMD just in case.
If this doesn't work, just move your project to disk D:
, as disk C:
is a system disk and it's typically more restrictive.
Upvotes: 1