none
LoadAndInstallApp() throws "System Account cannot perform this action" in feature receiver RRS feed

  • Question

  • I'm trying to install an add-in as a step in a feature activation via LoadAndInstallApp() method, but I get "The System Account cannot perform this action" exception.

    SPContext.Current is null in the feature receiver. I'm creating the site collection from Central Administration "Create Site Collection" page. Before executing LoadAndInstallApp() I enable side loading feature in the site collection.

    The best practice is to create a separate managed account for add-in installation, but do I really need to impersonate the current user in the feature receiver code in order for my code to work properly?

    UPD: the feature being activated is stapled to a custom template. The code which installs the app is executed when a user creates a new site collection in Central Administration using the custom template. The exception is not thrown when a user activates the feature manually via  'Site Settings => Site collection features' in the browser. Only the stapled execution leads to the exception.

    Wednesday, March 22, 2017 4:58 PM

All replies

  • Hi,

    SharePoint restricted system account to perform deploy or install an apps for security reason.

    Try to create a new user account as below and then construct the SPWeb based on new user account.

    https://social.msdn.microsoft.com/Forums/office/en-US/5eff54c9-36c6-41d1-9ddd-dd76680ace5f/error-occurred-in-deployment-step-install-app-for-sharepoint-the-system-account-cannot-perform?forum=sharepointdevelopment

    https://msdn.microsoft.com/en-us/library/ms469253.aspx

    Best Regards,

    Lee


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    • Marked as answer by Vadim Maximov Friday, March 24, 2017 7:47 AM
    • Unmarked as answer by Vadim Maximov Friday, March 24, 2017 1:17 PM
    • Marked as answer by Vadim Maximov Friday, March 24, 2017 1:17 PM
    • Unmarked as answer by Vadim Maximov Friday, March 24, 2017 1:17 PM
    Thursday, March 23, 2017 2:49 AM
  • I am using now the site collection administrator account to execute LoadAndInstallApp():

    SPUser user = web.EnsureUser(loginName);
    
    using (SPSite updatedSite = new SPSite(siteUrl, user.UserToken))
    {
        using (SPWeb updatedWeb = updatedSite.OpenWeb())
        {
            var appPackageStream = appCatalogItem.File.OpenBinaryStream();
            appInstance = updatedWeb.LoadAndInstallApp(appPackageStream);
        }
    }
    

    And after the execution of this code I see:

    When I click 'Click to retry' the app is installed normally. What do I miss? The code seems to be OK.

    (The code is executed as a part of a feature activation event receiver.)


    v

    Friday, March 24, 2017 1:17 PM
  • Hi,

    Could you try to debug the code and monitor if any exception?

    Here is the thread about debugging feature receiver for your reference.

    https://msdn.microsoft.com/en-us/library/ff798479.aspx?f=255&MSPPError=-2147217396

    Best Regards,

    Lee


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Monday, March 27, 2017 8:21 AM
  • SPUser user = web.EnsureUser(loginName);
    
    using (SPSite updatedSite = new SPSite(siteUrl, user.UserToken))
    {
        using (SPWeb updatedWeb = updatedSite.OpenWeb())
        {
            var appPackageStream = appCatalogItem.File.OpenBinaryStream();
    
            // throws exception "System account cannot perform this action"
            appInstance = updatedWeb.LoadAndInstallApp(appPackageStream);
        }
    }

    So, there's an exception, but I'm installing the app from under a different user that is a site collection owner:

    SPUser user = web.EnsureUser(loginName);

    Why does the app installation still take place on behalf of the system account? Is there a specific "state" of the site collection when the owner is not considered a "legitimate" user to install the app?

    Another point is when I click 'Details' in the app menu:

    I see no errors:



    Wednesday, March 29, 2017 10:23 AM
  • Hi,

    Seems something out of my expectation, I did test with below code.

    If I use below code, it will report below red error.( contoso\lee is the current user I log in to server, and it’s farm admin, also owner of site, not SharePoint system account))

    SPUser user=currentSite.RootWeb.EnsureUser("contoso\\lee");

    using (SPSite site = new SPSite(currentSite.ID,user.UserToken))

    Error occurred in deployment step 'Activate Features': Only users who can View Pages can list Apps.

    but if I run the code with current user permission, it works fine.

    //SPUser user=currentSite.RootWeb.EnsureUser("contoso\\lee");

    using (SPSite site = new SPSite(currentSite.ID))

    public override void FeatureActivated(SPFeatureReceiverProperties properties)
            {
                try
                {
                    SPSite currentSite=properties.Feature.Parent as SPSite;
                    //SPUser user=currentSite.RootWeb.EnsureUser("contoso\\lee");
                    using (SPSite site = new SPSite(currentSite.ID))
                    {
                        //if (null == site.WebApplication.Properties["AppCatalogUrl"])
                        //{
                        //    return;
                        //}
    
                        //get app catelog url from web application property
                        var appCatalogSiteUrl = "http://sp/sites/AppCatalog";//site.WebApplication.Properties["AppCatalogUrl"].ToString();
                        using (SPSite siteApp = new SPSite(appCatalogSiteUrl))
                        {
                            using (SPWeb webApp = siteApp.RootWeb)
                            {
                                SPList appList = webApp.Lists.TryGetList("Apps For SharePoint");
                                SPQuery query = new SPQuery
                                {
                                    Query = "<Where><Eq><FieldRef Name=\"Title\" /><Value Type=\"Text\">appUpdate</Value></Eq></Where>"
                                };
    
                                var items = appList.GetItems(query);
                                if (null != items && items.Count >= 1)
                                {
                                    SPListItem appCatalogItem = items[0];
    
                                    Guid appProductId = new Guid(appCatalogItem["AppProductID"].ToString());
                                    using (SPWeb web = site.RootWeb)
                                    {
                                        IList<SPAppInstance> existingInstances = web.GetAppInstancesByProductId(appProductId);
    
                                        if (existingInstances.Count > 0) throw new Exception("App is already installed in the target web");
    
                                        //Get the permission XML
                                        var appPermissionXml = appCatalogItem["AppPermissionXML"].ToString();
    
                                        //read the client Id from the Permission XML
                                        var xmlDoc = new XmlDocument();
                                        xmlDoc.LoadXml(string.Format("<Approot>{0}</Approot>", appPermissionXml));
                                        var root = xmlDoc.DocumentElement;
                                        var clientIdNode = root.SelectSingleNode("//@ClientId");
    
                                        //title and stream
                                        
                                        var appItemTitle = appCatalogItem.Title;
                                        var appPackageStream = appCatalogItem.File.OpenBinaryStream();
                                        var appInstance = site.RootWeb.LoadAndInstallApp(appPackageStream);
                                        
                                        
                                        return;
                                    }
                                }
                                else
                                {
                                    return;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

    Hope this would help you.

    Referenced thread.

    http://dinushaonline.blogspot.sg/2016/02/programmatically-upload-sharepoint-app.html

    Best Regards,

    Lee


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Thursday, March 30, 2017 8:49 AM
  • Thank you. The code you suggested works fine. But only when I activate the feature manually via 'Site Settings => Site collection features' in the browser.

    The problem I'm facing is that the feature which installs the app is stapled. So I try to install the app from a feature which is activated when I create a site collection from Central Administration using a custom template with this stapled feature. In this case it seems that the app installation code refuses to recognize the current user even if I create SPSite object using the constructor with the user token parameter:

    SPUser user = web.EnsureUser(loginName);
    
    using (SPSite updatedSite = new SPSite(siteUrl, user.UserToken))
    {
        using (SPWeb updatedWeb = updatedSite.OpenWeb())
        {
            var appPackageStream = appCatalogItem.File.OpenBinaryStream();
    
            // throws exception "System account cannot perform this action"
            appInstance = updatedWeb.LoadAndInstallApp(appPackageStream);
        }
    }


    Please, mark as answer, if this helps.


    Friday, March 31, 2017 1:24 PM
  • Now I'm trying to avoid stapled feature by implementing a delegate control that will install the provider-hosted add-in on the first user's visit of the site. But I get the exception:

    State-changing App lifecycle operations are disallowed on GET requests.
    SPWeb.AllowUnsafeUpdates = true does not help. Is this another restriction of the app security policy?


    Please, mark as answer, if this helps.


    Wednesday, April 5, 2017 12:30 PM
  • If you want to install spfx web parts as System Account for on-prem too please take a look at my blog post -> https://rasper87.wordpress.com/2018/04/26/provision-spfx-web-parts-to-classic-sites-part-3-install-spfx-web-part-to-sharepoint-site-web/
    Thursday, April 26, 2018 6:15 PM