UPDATE: It looks a little bit like a cross domain limitation. I was able to successfully complete a site creation within farm the WF is executed on via REST, but as soon as I attempt to hit another farm it gets an unauthorized failure. However, what is curious is the workflow is able to get the Form Digest value successfully from the other farm, but when the site creation is attempted (and passing in the form digest value) it is still failing with the following:

ResponseContent: {"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."}}}

Any thoughts?

End Update

We have a process in our environment for creating team sites for the business. Basically, the team requests the site and we start our process for determining metadata and security. I have most of this in a WF right now, but wanted to start using REST from the WF to create the sites. I am having no issues creating the sites within the same SharePoint farm, but part of our process is to also create the sites in the Dev and Test farms. This is where my snag is occurring.

Here is the process I am using:

  1. I first call the service: _api/contextinfo
  2. From there I grab the Form Digest value and store it in the WF.
  3. I then call the service _api/web/webinfos/add but in a different farm and passing the form digest value to it.

The System doesn't seem to be having any issues with the call itself as the error being returned is Unauthorized and not Bad Request or something like that as I would expect for poorly formed REST call. One of the things I would like to point out is the site creation is done in an App Step and I manually added the APP Guid to my app permissions in the separate farm and granted it full control as per the following:

   <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />

Because the farm that is sending the request isn't part of the farm receiving the request, the Lookup didn't work when I entered the app GUID, but I did fill in the information in the fields correctly.

As near as I can tell everything is configured correctly, so now I am wondering if this is even possible as everything I can find on the net is for creating WF within the same farm. I can't see why this wouldn't work as you can perform these steps in code, but maybe SPD is doing something differently behind the scenes. Any thoughts?

BTW, here's the full ResponseContent I get back for the call to create the site:

> Response Content: {"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."},"innererror":{"message":"Access is denied. (Exception
> from HRESULT: 0x80070005
> (E_ACCESSDENIED))","type":"System.UnauthorizedAccessException","stacktrace":"
> at
> Microsoft.SharePoint.SPGlobal.HandleUnauthorizedAccessException(UnauthorizedAccessException
> ex)\u000d\u000a at
> Microsoft.SharePoint.Library.SPRequest.OpenWeb(String bstrUrl, String&
> pbstrServerRelativeUrl, String& pbstrTitle, String& pbstrDescription,
> String& pbstrTitleResourceId, String& pbstrDescriptionResourceId,
> Guid& pguidID, DateTime& pdtTimeCreated, String&
> pbstrRequestAccessEmail, UInt32& pwebVersion, Guid& pguidScopeId,
> UInt32& pnAuthorID, UInt32& pnLanguage, UInt32& pnLocale, UInt16&
> pnTimeZone, Boolean& bTime24, Int16& pnCollation, UInt32&
> pnCollationLCID, Int16& pnCalendarType, Int16& pnAdjustHijriDays,
> Int16& pnAltCalendarType, Boolean& pbShowWeeks, Int16&
> pnFirstWeekOfYear, UInt32& pnFirstDayOfWeek, Int16& pnWorkDays, Int16&
> pnWorkDayStartHour, Int16& pnWorkDayEndHour, Int16& pnMeetingCount,
> Int32& plFlags, Boolean& bConnectedToPortal, String& pbstrPortalUrl,
> String& pbstrPortalName, Int32& plWebTemplateId, Int16&
> pnProvisionConfig, String& pbstrDefaultTheme, String&
> pbstrDefaultThemeCSSUrl, String& pbstrThemedCssFolderUrl, String&
> pbstrAlternateCSSUrl, String& pbstrCustomizedCssFileList, String&
> pbstrCustomJSUrl, String& pbstrAlternateHeaderUrl, String&
> pbstrMasterUrl, String& pbstrCustomMasterUrl, String&
> pbstrSiteLogoUrl, String& pbstrSiteLogoDescription, Object& pvarUser,
> Boolean& pvarIsAuditor, UInt64& ppermMask, Boolean& bUserIsSiteAdmin,
> Boolean& bHasUniquePerm, Guid& pguidUserInfoListID, Guid&
> pguidUniqueNavParent, Int32& plSiteFlags, DateTime&
> pdtLastContentChange, DateTime& pdtLastSecurityChange, String&
> pbstrWelcomePage, Boolean& pbOverwriteMUICultures, Boolean&
> pbMUIEnabled, String& pbstrAlternateMUICultures, Int32&
> plSiteSchemaMajorVersion, Int32& plSiteSchemaMinorVersion, Int32&
> plSiteSchemaBuildVersion, Int32& plSiteSchemaRevisionVersion, Int32&
> puiVersion, Int16& pnClientTag, Boolean& pfIsEvalSite, Guid&
> pgSourceSiteId, DateTime& pdtExpirationDate, Guid& pgEvalSiteId, Guid&
> pguidAppProductId, String& pbstrRemoteAppUrl, String& pbstrOAuthAppId,
> String& pbstrAppDatabaseName, Guid& pgAppDatabaseServerReferenceId,
> String& pbstrAppDatabaseTargetApplicationId, String&
> pbstrAppWebDomainId, Int32& plUpgradeFlags, DateTime& pdtReminderDate,
> UInt64& pmaskDeny)\u000d\u000a at
> Microsoft.SharePoint.SPWeb.InitWeb()\u000d\u000a at
> Microsoft.SharePoint.SPWeb.get_Description()\u000d\u000a at
> Microsoft.SharePoint.SPWeb.get_Webs_Client()\u000d\u000a at
> Microsoft.SharePoint.ServerStub.SPWebServerStub.GetProperty(Object
> target, String propName, ProxyContext proxyContext)\u000d\u000a at
> Microsoft.SharePoint.Client.ServerStub.GetPropertyWithMonitoredScope(Object
> target, String propertyName, ProxyContext proxyContext)\u000d\u000a at
> Microsoft.SharePoint.Client.Rest.RestRequestProcessor.GetObjectFromPathMember(Boolean
> mainRequestPath, String path, Object value, EdmParserNode node,
> Boolean resourceEndpoint, MethodInformation& methodInfo)\u000d\u000a
> at
> Microsoft.SharePoint.Client.Rest.RestRequestProcessor.GetObjectFromPath(Boolean
> mainRequestPath, String path, String pathForErrorMessage)\u000d\u000a
> at
> Microsoft.SharePoint.Client.Rest.RestRequestProcessor.Process()\u000d\u000a
> at
> Microsoft.SharePoint.Client.Rest.RestRequestProcessor.ProcessRequest()\u000d\u000a
> at Microsoft.SharePoint.Client.Rest.RestService.ProcessQuery(Stream
> inputStream, IList`1 pendingDisposableContainer)"}}}
  • This seems like a strange setup, but have you tried getting the FormDigest from your target farm and then POST'ing with that on the target farm?
    – iOnline247
    Jan 7, 2016 at 20:09
  • Thanks for the reply. That's exactly what I am doing. Workflow runs on FarmA. It gets the FormDigest successfully from FarmB and stores within a workflow variable. The WF then attempts to fire the REST call against https://<FarmB>/_api/web/webinfos/add. It passes in the FormDigest value. Jan 7, 2016 at 20:49
  • Sounds similar to the issue here: fabiangwilliams.com/2014/06/19/… Give that a go and see if you can spot the issue in your setup.
    – iOnline247
    Jan 12, 2016 at 15:36
  • Thanks for the reply. Yah, I read the post by Fabian and it further makes me believe this can't be done. Even though I can get the FormDigest, I still do not have the necessary rights to add the spWeb because I am doing it outside of the site collection (and the domain for that matter). Jan 12, 2016 at 15:54
  • 1
    Yah, I have given up on the SPD method for now. What I have switched to is a Custom Action that calls a page that first populates the new site information for user confirmation and then calls the site creation API. This happens entirely within the second farm so it should work in theory. If I get it to work, will update the solution here if you are interested. Jan 12, 2016 at 21:54


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.