none
HttpSend to call custom wcf service RRS feed

  • Question

  • Hi,

    I've developed a workflow in Visual Studio and that is invoking a custom WCF service that I've developed.  But the workflow gets '401 Unauthorized' while try to access the cusom service. I've used a network monitor to find out the details. However the workflow can access the SharePoint contents using out of the box REST API.

    After investigating the http traffic, I've found while the workflow is calling REST API, the http header 'authorization' has access-token filled automatically. However while my custom workflow is invoked by workflow, the authorization header is just 'Bearer', so access-token is missing. Is there any way I can access the token in workflow and pass it in header to call my custom wcf server? Or is there any suggestion on how to call custom wcf service from sharepoint workflow 2013?


    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com


    • Edited by Sohel Rana Tuesday, March 5, 2013 2:44 AM
    Thursday, February 28, 2013 3:49 AM

All replies

  • Sohel, have you looked at the Workflow Activities APIs for what you are trying to accomplish?  They can found here: http://msdn.microsoft.com/en-gb/library/microsoft.workflow.activities.aspx.  I would assume that for the scenario you are presenting here you are trying to send a HeaderRequest with the required access-token?   If so, HttpSendRequestHeader should to the trick. 

    Let me know,

    Chris

    Thursday, February 28, 2013 9:16 PM
  • Hi Chris,

    Thanks for your reply.

    I've been using HttpSendRequestHeader for sending other headers like 'content-type', 'accept'. But the problem is I don't have access token. The workflow has the token anyhow, as it's being used to call SharePoint REST API. Workflow Manager is passing the token automatically when I'm calling REST API. But when I'm calling my custom WCF service, the token is not passed to my service. If I could have access to the token (or at least knew how to access the token from workflow context), I could use the token to call my custom WCF service.


    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    Friday, March 1, 2013 1:03 AM
  • Hi Sohel,

    You can overwrite the system-provided Authorization header by specifying your own value in the RequestHeaders collection for the HttpSend activity.  You can provide your own credential there to authenticate to your custom WCF service.

    The Bearer token that is used to call SharePoint APIs cannot be used as a credential to call your service, as that would be would in an unsupported delegation pattern.

    Hope that helps,

    -- Dave

    (Note: the link that Chris provided was for some older APIs that are no longer relevant, so please ignore.)

    • Proposed as answer by Chris Shaw - MSFT Saturday, March 2, 2013 12:35 AM
    • Unproposed as answer by Sohel Rana Sunday, March 3, 2013 3:16 AM
    Friday, March 1, 2013 11:56 PM
  • Hi Dave,

    I would like to pass the access token in authorization header. But I don't have the access token. How can I get the access token from Workflow Manager context and pass it to the authorization header? If I don't have access to the access token then how can I can call a custom WCF service? Is it not supported in this release? If there's any workaround can you please provide links to documentation? Since calling service is the only way to implement business logic, there's should have strong support for calling external services. I'm giving up with this Workflow Manager. Though the technology seems very appealing but if it takes more time to develop, clients not gonna pay for that extra time.


    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com



    • Edited by Sohel Rana Sunday, March 3, 2013 3:19 AM
    Sunday, March 3, 2013 3:15 AM
  • Hi Sohel,

    The access token that Workflow Manager provides is solely for the purpose of calling back to SharePoint, and the credential is only useful for that.  Workflow Manager cannot automatically authenticate to your custom WCF service without you providing the credential to access it, which you can do by setting the Authorization header explicitly in the workflow.

    -- Dave

    Monday, March 4, 2013 7:23 PM
  • Hi Dave,

    I've developed the custom WCF service with MultipleBaseAddressWebServiceHostFactory' and deployed in SharePoint 2013. So the custom WCF service is also a SharePoint WCF service developed using recommendation as described here: http://msdn.microsoft.com/en-us/library/ff521581.aspx. Now

    • I need to pass the access token in Authorization header while I'm calling my custom WCF service deployed in SharePoint.
    • I can't access Workflow's internal access token.

    Since I can't access the Workflow Manager access token, I need to call to SharePoint to get back the access token. As I've found, Javascript library and C# code are the only way to extract access token back from SharePoint but none of them are supported in Workflow. Is there any viable option to get the access token back from SharePoint?

    So my simple problem comes to a single point now. How can I authenticate my custom WCF Service (which is deployed in SharePoint and using SharePoint integrated authentication)? I know I need to pass authorization header, but where I can get the authorization header value? WF Manager will not allow it's own access token, but I need access token and there's no sample how to extract access token from SharePoint in Workflow Manager.


    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com


    • Edited by Sohel Rana Tuesday, March 5, 2013 1:47 AM
    Tuesday, March 5, 2013 1:46 AM
  • Do you solve this issue? I have the similary problem.
    Tuesday, March 19, 2013 7:45 AM
  • No, I've not got any solution for this. I was planning to use workflow model for a new SharePoint project. In this first phase we've installed/configure Information Architecture and now next month, we're going to start second phase. In second phase, we'll need to implement some very complex workflow and I need custom wcf services to be used for the workflow. But I've not found a single example in the universe that will explain how to call a custom WCF service from workflow though WCF service is the only way to implement custom logic in SharePoint 2013 workflow. I'm out-of-ideas!!!!. I've spent many hours to figure out the solutions but without help from workflow/SharePoint team, its dead-end now, Very frustrating though! I’m not to blame but it seems there’s a communication gap between Workflow team and SharePoint team.


    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    Tuesday, March 19, 2013 11:42 AM
  • Is bearer authorization critical for you?

    Tuesday, March 19, 2013 3:23 PM
  • Without this token, I get access denied error. I've a very simple requirement, I have a custom WCF service deployed in SharePoint. I would like to call this WCF Service from Workflow. Any example?

    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    Wednesday, March 20, 2013 2:28 AM
  • What method returns access denied? Something like SPListItem.Update()?
    Wednesday, March 20, 2013 8:04 AM
  • What method returns access denied? Something like SPListItem.Update()?
    When I try to call custom WCF service from workflow I get access denies. I've confirmed that my method is not throwing the exception as before the request is passed to my service/method, SharePoint is throwing the exception as the request is missing secuirty token. Before sending the request to WCF service from workflow, I need to include security token to the request, but the secuirty token is not accessible from workflow runtime as it's internal. If you please read the thread fom the beginning, I hope you will get the insight into the problem.

    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    Wednesday, March 20, 2013 10:15 AM
  • I'm in deep research of this problem now. I have found, that if I add http-header Authorization = "" call to my custom service executed correctly. But I want to find completely correct way to build service that support bearer authorization.

    Did you try call you service with Authorization = ""?

    Wednesday, March 20, 2013 11:40 AM
  • Finally. I have intermediate solution for creating service that can be consumed by workflow HttpSend activity.

    1. Create wcf service and deploy it to SharePoint farm.

    2. Add requestHeader Authorization="" to you HttpSend activity.

    3. You service will be call anonymously but you can use http-pool account using elevation.

    Example:

            public void ProcessRequest(HttpContext context)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite site = new SPSite("http://novasp15:90/"))
                    {
                        using (SPWeb web = site.OpenWeb())
                        {
                            SPList list = web.GetList("Lists/Products");
    
                            SPListItem newItem = list.AddItem();
                            newItem["Title"] = string.Format("New Item {0};", DateTime.Now.Ticks.ToString());
                            newItem.Update();
                        }
                    }
                });
            }
    


    Wednesday, March 20, 2013 12:33 PM
  • Hi,

    To invoke the WCF service anonymously, I need to enabled anonymous access to the SharePoint site. But in my case, I can't use anonymous access as the site is running on Intranet and client doesn't want to use anonymous access.


    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    Monday, March 25, 2013 7:39 AM
  • In my tests anonymous access is not enabled. But calls to my service passed right.

    Request headers looks like:

    GET /_vti_bin/MLClient.svc/web/title/ HTTP/1.1
    Authorization: NTLM TlRMTVNTUAABAAAAB7IIogQABAAwAAAACAAIACgAAAAGAvAjAAAAD05PVkFTUDE1VkxBQg==
    Host: novasp15:90
    X-MS-WF-RequestorId: 1304d1fd-580d-5b3e-65d5-28f58b114b77
    client-request-id: eb0f7467-afad-4818-8eb8-decffe0bb8bf
    SPIisTimeStamp: NOVASP15:11137403274634
    

    What is you authorization settings?
    Monday, March 25, 2013 9:39 AM
  • Looks like list of services with bearer authorization is hardcoded in static constructor of SPOAuth2EndpointIdentityFactory.

    static SPOAuth2EndpointIdentityFactory()
    {
        SPApplicationAuthenticationAllowedEndPoint[] pointArray = new SPApplicationAuthenticationAllowedEndPoint[5];
        SPApplicationAuthenticationAllowedEndPoint point = new SPApplicationAuthenticationAllowedEndPoint();
        point.RelativeEndPoint = "/_vti_bin/client.svc";
        point.ApplicationId = "00000003-0000-0ff1-ce00-000000000000";
        pointArray[0] = point;
        SPApplicationAuthenticationAllowedEndPoint point2 = new SPApplicationAuthenticationAllowedEndPoint();
        point2.RelativeEndPoint = "/_vti_bin/listdata.svc";
        point2.ApplicationId = "00000003-0000-0ff1-ce00-000000000000";
        pointArray[1] = point2;
        SPApplicationAuthenticationAllowedEndPoint point3 = new SPApplicationAuthenticationAllowedEndPoint();
        point3.RelativeEndPoint = "/_vti_bin/sites.asmx";
        point3.ApplicationId = "00000003-0000-0ff1-ce00-000000000000";
        pointArray[2] = point3;
        SPApplicationAuthenticationAllowedEndPoint point4 = new SPApplicationAuthenticationAllowedEndPoint();
        point4.RelativeEndPoint = "/_api/";
        point4.ApplicationId = "00000003-0000-0ff1-ce00-000000000000";
        pointArray[3] = point4;
        SPApplicationAuthenticationAllowedEndPoint point5 = new SPApplicationAuthenticationAllowedEndPoint();
        point5.RelativeEndPoint = "/_vti_bin/wopi.ashx";
        point5.ApplicationId = "wopi";
        pointArray[4] = point5;
        s_AllowedEndPoints = pointArray;
    }
    
     
    

    Hence the only way to create such service is to override one of services listed above.

    For example, you can rewrite client.svc with you custom service. In implementation of you service you must call original service handler. But this is hack and not appropriate for regular scenarios.

    Monday, March 25, 2013 3:25 PM
  • I've enabled Anonymous access at web application level but not in site collection level. Now I can invoke the wcf service. Thanks for your findings Sergey. But I'm not sure if this is a good idea from security point of view. In WCF service I also need the code to be executed by the initiator user context which I would get automatically if workflow and WCF could talk to each other with OAuth without anonymous. However I think I can pass the Initiator name to WCF service from workflow and then inside WCF service I can try to execute the code with initiator's privileges.

    I think with this approach I can save myself in my current project but still I'm looking for possibly the solution that will work without anonymous authentication


    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    Tuesday, March 26, 2013 1:25 AM
  • I would also like to see a proper solution to this issue.

    Wednesday, May 29, 2013 4:46 AM
  • Hi Russel,

    I think the issue is fixed at least for me. I had the anonymous issue problem but that's also been resolved after applying latest SharePoint updates. You can find more details on how to create WCF service and use it from workflow in my blog with source code: http://ranaictiu-technicalblog.blogspot.com.au/2013/04/sharepoint-2013-workflow-use-httpsend.html


    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    Wednesday, May 29, 2013 5:43 AM
  • I think the issue is fixed at least for me. I had the anonymous issue problem but that's also been resolved after applying latest SharePoint updates.

    To clarify: are you saying that after you applied SharePoint updates that you can now query customer SP 2013 web service without enabling anonymous on the web application? If so does its just work as expected or do you still have to do some playing around with tokens?

    (PS: hey Sohel, I see you are from Perth. Do you work from the NEC building in Technology Park?)

    Wednesday, May 29, 2013 5:50 AM
  • What I did, I applied SharePoint March Update and Workflow Manager 1.0 update and re-registered the workflow. One thing you need double check that you need to pass 'authorization' header to empty and don't provide any security token in the request.

    (Yes I'm from Perth and no, I don't sit in Tech Park, I sit in CBD office.)


    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    • Proposed as answer by Russell Munro Wednesday, May 29, 2013 8:00 AM
    Wednesday, May 29, 2013 6:20 AM
  • Sohel have you had success requesting a custom web service with a SharePoint Designer?

    Thanks to the help you gave above I can request custom web services from a VS solution but not from SharePoint Designer.

    I tried added request header with Authorization "" (also, blank didnt work) but had no success. Others have also tried also but no sucess: http://social.technet.microsoft.com/Forums/en-US/sharepointitpropreview/thread/f54b8c1d-9c06-4f4a-bba9-b22dcb6e1cdc/

    do you think you can solve this problem?

    Monday, June 10, 2013 7:28 AM
  • Hi,

    • Is it a custom WCF service or just web service? is it RESTful or not?
    • Can you call the same service from a web part (just to ensure it the service call works)
    • Can the workflow call SharePoint out-of-the-box REST API endpoint?

    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    Monday, June 10, 2013 7:54 AM
  • Yep it could do everything you suggest. I deleted the workflow and restarted and then the workflow worked fine (Authorization = blank). Perplex, I repeated everything I did previous and found out what the problem was... me.

    Let me document it for other people as its is a bit of a gotcha...

    1) I tried Authorization = "", ran the workflow and recieved a suspended error: 'The format of value '""' is invalid.'

    2) I then tried Authorization = blank, ran the workflow and saw a suspended error.
    3) I then repeated this over, tried "Accept" and "Content Type" and other params but kept seeing suspended error.

    In each case The "Running Workflows" continued to show "Suspended". BUT that is because all the workflow I ran after the original Suspended error (1) were immeditely failing and appearing in the "Completed Workflows" list. They Terminiated because the original workflow was still considered to be running. The net result is the illusion that all my changes in SPD were failing.

    So.... make sure you terminate your Supended WFs before re-running them!

    Thanks again Sohel for your time and sorry for bothering you.

    Monday, June 10, 2013 8:27 AM
  • yes that's true. Suspended workflow means still running as I had found and you can't run the same workflow definition again until you terminate the suspended workflow.

    Thanks,
    Sohel Rana
    http://ranaictiu-technicalblog.blogspot.com

    Monday, June 10, 2013 9:15 AM
  • Hi,

    I'm also looking for a solution to this problem. Isn't there any possibility to provide the web service running in SharePoint with the security token of the initiator of the workflow.


    Maik

    Monday, July 22, 2013 6:59 AM
  • I have tested HTTPSend activity's authorization attribute as "" with HTTPs site (Site and workflow service app both are running on HTTPs) and it's working fine.
    Saturday, March 1, 2014 9:07 PM
  • I have tested HTTPSend activity's authorization attribute as "" with HTTPs site (Site and workflow service app both are running on HTTPs) and it's working fine.

    it's not working on sharepoint online : sharepoint.com.

    In my httsend i use Authorization = ""

    => OK on dev machine sharepoint 2013

    => KO on sharepoint.com

    with http://msdn.microsoft.com/en-us/library/office/jj822159(v=office.15).aspx

    => KO UnauthorizedAccessException


    Vincent G

    Wednesday, March 12, 2014 3:45 PM
  • I have tested HTTPSend activity's authorization attribute as "" with HTTPs site (Site and workflow service app both are running on HTTPs) and it's working fine.

    it's not working on sharepoint online : sharepoint.com.

    In my httsend i use Authorization = ""

    => OK on dev machine sharepoint 2013

    => KO on sharepoint.com

    with http://msdn.microsoft.com/en-us/library/office/jj822159(v=office.15).aspx

    => KO UnauthorizedAccessException


    Vincent G

    I find a solution for SharePoint online:

    in my workflow i use activity : GetS2SSecurityToken

    and i'm pass this token in property SecurityToken of activity HttpSend

    But with this solution now, it's not working in my dev env. so i suppose there's some trouble with authentification NTLM and cookie from SharePoint online. But I'm happy it's work on SharePoint.com


    Vincent G

    • Proposed as answer by Hervé DORIER Friday, March 14, 2014 3:31 PM
    • Unproposed as answer by Sohel Rana Saturday, March 15, 2014 11:38 AM
    Friday, March 14, 2014 3:25 PM