Recycle App Pool Programmatically in IIS 10 / Windows Server 2019 - iis

I'm trying to create a function that will allow a user to reset/recycle an application pool on demand in order to reload updated IIS site settings, however I'm running into a permissions issue anytime I try to use a ServerManager function.
ServerManager serverManager = new ServerManager();
ApplicationPool appPool = serverManager.ApplicationPools[site_list.SelectedValue];
if (appPool != null) {
if (appPool.State == ObjectState.Stopped) {
appPool.Start();
} else {
appPool.Recycle();
}
}
Any time I run the code, I get the following error:
Filename: redirection.config Error: Cannot read configuration file due
to insufficient permissions
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details: System.UnauthorizedAccessException: Filename:
redirection.config Error: Cannot read configuration file due to
insufficient permissions
ASP.NET is not authorized to access the requested resource. Consider
granting access rights to the resource to the ASP.NET request
identity. ASP.NET has a base process identity (typically
{MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6 and IIS 7, and
the configured application pool identity on IIS 7.5) that is used if
the application is not impersonating. If the application is
impersonating via , the identity will be
the anonymous user (typically IUSR_MACHINENAME) or the authenticated
request user.
To grant ASP.NET access to a file, right-click the file in File
Explorer, choose "Properties" and select the Security tab. Click "Add"
to add the appropriate user or group. Highlight the ASP.NET account,
and check the boxes for the desired access.
I've tried granting read permissions to the redirection.config file to any/all of the following users with no change:
ASPNET
NETWORK SERVICE
IUSR
IIS_IUSRS
Anyone happen to have any insight on how to recycle an AppPool through code?

I can get it work when I set application pool identity to LocalSystem and anonymous authentication->Edit->Use application pool identity.
I think if you don't want to use LocalSystem, then you have to grant special permission for C:\Windows\System32\inetsrv\config folder and your application root folder. It will also reduce the security of your computer.
Microsoft Process monitor could help you grant NTFS permission. You could add a filter for "process name=w3wp.exe" and "result=access denied".
https://learn.microsoft.com/en-us/sysinternals/downloads/procmon

Related

Azure Active Directory copy data source connection with "SharePoint Online"

I am connecting to a linked service to SharePoint Online using Azure Data Factory. I have admin access to everything on my site and in the Active Directory.
I have granted Site.FullControl() permission to my site in "App registration" and also granted in SharePoint site but still it is showing me I don't know what else to do.
This is the error I get:
Failed to get metadata of OData service, please check if service URL and credential is correct and your application has permission to the resource. Expected status code: 200, actual status code: Unauthorized, response is : {"error":"invalid_request","error_description":"Token type is not allowed."}.
Activity ID: 4cc5411a-2932-40c9-baaa-c77a22f9270a.

Get 401 Unauthorised calling WebApi from another WebAp on behalf of api (not user)

We have a number of ASPNET Core Web Apis in Azure that we call on behalf of a User. That user has normally signed into an ASPNET Web Site, also in Azure.
We are introducing an Audit Service. That feels like it should be called on behalf of the calling service rather that the authenticated user.
The Audit Service has an associated App Registration in Azure AD
The Audit Service has a scope called "access_as_application" although having seen documentation about a ".default" scope I wasn't sure that i needed a scope
The calling application (ASPNET Core Web Site) has been added in the "Authorized client applications" section against the previously mentioned scope
In the calling application I am getting an access token for the app rather than the user by using GetAccessTokenForAppAsync.
var accessToken = await this.tokenAcquisition.GetAccessTokenForAppAsync(this.auditApiScope);
System.Diagnostics.Debug.WriteLine($"access token-{accessToken}");
this.httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Currently I am running the calling application and the audit service on my local development machine.
When I make the call to the audit service I am getting a 401 Unauthorized
var response = await this.httpClient.PostAsync($"{this.auditApiBaseAddress}v1/entries", requestContent);
UPDATE
I have added the Azure Ad App Id of the calling application as a knownClientApplication on the Audit Service, via the App Manifest. That did not prevent the 401
"knownClientApplications": [
"7ac7f49d-e9fa-4e1b-95b2-03e0e1981f58"
],
UPDATE 2
I can see that the instance of the service running in Visual Studio is reporting a stack trace. It is referring to a IDW10201 issue.
System.UnauthorizedAccessException: IDW10201: Neither scope or roles claim was found in the bearer token.
at Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilderExtensions.<>c__DisplayClass3_1.<<AddMicrosoftIdentityWebApiImplementation>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilder.<>c__DisplayClass14_0.<<CallsWebApiImplementation>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Any thoughts why?
You should currently be performing server-to-server interaction, that is, no user involvement. So your server application needs to create an appRole, and then grant the app Role as an application permission to the client application.
First, you need to expose the api of the server application protected by Azure, which can be configured according to the following process:
Azure portal>App registrations>Expose an API>Add a scope>Add a client application
Then you need to create the appRole of the server application, and then grant that role as an application permission to the client application.
Next, go to client application>API permissions>Add a permission>My APIs>your api application.
Finally, you need to obtain an access token using the client credential flow where no user is logged in:
Parse the token:
Whilst I've marked Carl Zhao's contribution as the answer I found the screenshots a bit hard to follow so this is my attempt at making that a bit clearer.
In this scenario where we want authentication between Azure Ad registered application (client) and another Azure Ad registered application (Audit Service) scopes were not the solution. Rather than exposing a scope we needed to expose an appRole.
The steps required to expose and then request access to the app role were
App Registrations -> Audit Service -> Manage -> App roles -> Create app role
When creating the app role ensure the Allowed member type is "Applications"
Now go to App Registrations -> YourClientApplication -> Api permissions -> Add a permission
I expected the Audit Service to appear under "My APIs" in the "Request API permissions panel". I did not, the only way I could request permisison to the previously created AppRole was to enter the AppId of the Audit Service in the search box under "APIs my organization uses"
Once I was able to select the audit service I selected "Application permissions" rather than "Delegated permissions" and then I selected the specific role
Once the client application had been granted access we needed to write code get to an access token. Using Mictosoft.Identity.Web library
var accessToken = await this.tokenAcquisition.GetAccessTokenForAppAsync(this.auditApiScope);
System.Diagnostics.Debug.WriteLine($"access token-{accessToken}");
this.httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Note the call to GetAccessTokenForAppAsync not GetAccessTokenForUserAsync. GetAccessTokenForAppAsync still requires a scope however as already stated a custom scope is not needed. The scope is ".default" so the string passed to that call in our case was https://ourdomain/audit-service/.default" which is our App ID URI plus ".default"

Unexpected 403 in Sharepoint rest api list items roleassignments call

We created a sharepoint add-in with the follow permissions:
<AppPermissionRequests AllowAppOnlyPolicy="true"><AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="Read"/></AppPermissionRequests>
My understanding is that an app with tenant scope permissions should be able to read all the site contents. In this case the call to
/_api/web/lists('<id>')/items(<id>)/roleassignments
fails with the following error:
Client error 403
{
"odata.error":
{
"code":"-2147024891, System.UnauthorizedAccessException",
"message":
{
"lang":"en-US",
"value":"Access denied. You do not have permission to perform this action or access this resource."
}
}
}
Note that a call to /_api/web/lists('<id>')/items(<id>) for the same item works fine. The roleassignments call with tenant permissions is also working for one of the SPO instances but not for a different one.
We've struggled with this issue on and off, because the solution is not obvious, nor even sensible from a least-privilege perspective. In short:
Your application requires FullControl rights in order to access RoleAssignments.
More details
If using an application created by Azure AD, you can demonstrate this by granting and consenting to SharePoint permissions such as:
AllSites.Read (delegated)
MyFiles.Read (delegated)
Sites.Selected (application)
User.Read.All (delegated)
User.Read.All (application)
If using SharePoint-created application, use appregnew.aspx and appinv.aspx to create the app and grant it Read rights at some reasonable scope; try http://sharepoint/content/tenant.
Then get a bearer token using a client_credentials workflow (use Postman, for example).
Try a query like:
https://your-tenant.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')/Files?$select=Length,TimeLastModified,ListItemAllFields,ServerRelativeUrl
Make sure the Authorization header value is Bearer your-access-token
It will work.
Now try the same query, but with getting role assignments:
https://your-tenant.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')/Files?$select=Length,TimeLastModified,ListItemAllFields,ServerRelativeUrl&$expand=ListItemAllFields/RoleAssignments/RoleDefinitionBindings/Name
It will fail as you described, with status 403 and System.UnauthorizedAccessException.
Now grant and consent to the SharePoint application permission Sites.FullControl.All, or use appinv.aspx to add FullControl rights. Get a new bearer token. (The old one encodes the old rights granted to the app in the role field of the payload.). You'll need to wait a few minutes until the permissions apparently propagate from AD to SharePoint, if you're using an Azure AD application.
Try the last query again, and it will work.
IMHO, requiring FullControl in order to resolve something like a role assignment, which is needed to capture the permissions required to access content in a SharePoint library, is unjustified. I could understand, sort of, if tenant-scope Read permission were required. However, granting AllSites.Read or tenant-scope (http://sharepoint/content/tenant in appinv.aspx XML permissions) doesn't seem to enable roleassignment lookup.

Azure Admin Consent in multi tenant not working

I've some problems with the admin consent in a multi tenant environment.
So here is my structur.
Tenant 1
Tenant 2
I've got registered one ActiveDirectory Aapp in Tenant 1, called "App1".
In this App, I set i.e. permissions for Microsoft Graph.
Then I granted this permission.
Now I want to have also this App1 in my Tenant 2, so I do an AdminConsent with:
https://login.microsoftonline.com/TenantID_of_Tenant2/adminconsent?client_id=ClientID_of_App1
It worked fine. A few minutes later I saw App1 in Tenant2 and I was able i.e. to give access right to App1 for Users of Tenant2. No problem.
So then I had to give my App1 a few more permissions. So I clicked
"App registrations" in Tenant1 and gave more permissions for Microsoft Graph.
Then I clicked to "Enterprise Applications" in Tenant1, selected my App1 -> Permission and then "Grant admin consent for tenant1". A new browser was opened and I was able to do the admin consent for App1 in Tenant1.
Then I thought that I have to do the same in Tenant2, because it works the first time. So in Tenant2 I also navigated to ActiveDirectory -> Enterprise Applications -> selected my App1 -> Permissions
Here I saw the first permissions which I granted. Then I clicked to "Grant admin consent for Tenant2". A new browser was opened, but now it failed with folowwing error:
https://myRedirectURL/?error=access_denied&error_description=AADSTS65005%3a+The+application+%clientID_of_App1%27+asked+for+permissions+to+access+a+resource+that+has+been+removed+or+is+no+longer+available.+Contact+the+app+vendor.%0d%0aTrace+ID%TraceID%0d%0aCorrelation+ID%CorrelationIDaTimestampTimestamp&admin_consent=True&tenant=TenantID_of_Tenant2
Better to read: Error:
"AADSTS65005. The application ID_App1 asked for permissions to access a resource that has been removed or is no longer available. Contatct the app vendor."
I get the same error when I invoke the URL https://login.microsoftonline.com/TenantID_of_Tenant2/adminconsent?client_id=ClientID_of_App1
But I didn't do anything...so wheres the problem?
For your Redirect URI error you can try these steps:
Set the resource in your request to Azure AD.
Ensure that the client Id of the WebApp is configured in the WebApi's "knowClientApplications" array property in the manifest file
Ensure that all permissions are correct (APIs are added as delegated permissions to the client).
Ensure that all services (web app & apis) are multi tenant
Update manifest with:
"availableToOtherTenants": true,
"knownClientApplications": [
"{client app application id}"
],
See also the troubleshooting steps in these similar threads:
Azure AD error when fetching access token & login
The client application has requested access to resource 'https://outlook.office365.com'. This request has failed

Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046}

i use Windows XP_SP_3 and IIS 5 (local host), build site with asp.net4 and use this code:
Application appClass = new Application();
Document wordDoc = appClass.Documents.Add(Server.MapPath("~") + #"Files\tmp.docx");
wordDoc.SaveAs(#"e:\hp\Files\" + TextBox1.Text + ".docx");
wordDoc.Close();
if run site with VS2010, its OK. but if run with IIS 5 (Local Host), show this error:
Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.UnauthorizedAccessException: Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET request identity. ASP.NET has a base process identity (typically {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6 and IIS 7, and the configured application pool identity on IIS 7.5) that is used if the application is not impersonating. If the application is impersonating via , the identity will be the anonymous user (typically IUSR_MACHINENAME) or the authenticated request user.
To grant ASP.NET access to a file, right-click the file in Explorer, choose "Properties" and select the Security tab. Click "Add" to add the appropriate user or group. Highlight the ASP.NET account, and check the boxes for the desired access.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
I open Component Service > Computer > right click in My Computer > choose Properties > COM Sucrity > Launch and Activation... > Edit Default > Add > Advanced >
i not Find User IIS (IIS_IUSRS). so Choose ASP.NET and ok and Check Local Launch & Remote Launch & Local Activation & Remote Activation.
rest System and run site with iis5 again. but show error previous again!
Goto Control panel -> Administrative Tools -> Component
Services
Expand Tree by clicking on Component Services ->
Computers -> My Computer -> DCOM Config
Search CLSId
00020906-0000-0000-C000-000000000046 (which is for word application)
Note: If Search CLSId not finds then search by "Windows Word Application".
By selecting
00020906-0000-0000-C000-000000000046 this CLSId now right click on Properties
In the Propeties area, click on Security TAB.
Select Customize option from all (Launch and Activations
Permissions, Access Pemissions, Configuration Permissions).
Add new name as NETWORK SERVICE in all, and Allow all permissions for
this name.
Go to Identity TAB in the same properties area, select
option as a This user and then add username (which is
administrator of this machine) and password. Click on Apply, Ok.
Refresh Component Services and check your application is working
fine or not.
Start Internet Information Services (IIS).
Right-click your application's virtual directory, and then click Properties.
Click the Directory Security tab.
Under Anonymous access and authentication control, click Edit.
Make sure the Anonymous access check box is not selected and that Integrated Windows authentication is the only selected check box.
Configure ASP.NET to use Windows authentication with impersonation, use the following configuration
...
<authentication mode="Windows"/>
<identity impersonate="true"/>
...

Resources