1

Below is my WCF service which i have created. I was able to access this service with in the domain.However i want to make this service available across domain through BCS from sharepoint designer. Can you please help me what to make changes in Web.config file and the code so that it is accessible across domain.My Web.config is below.

public Vendor[] GetVendors(string strFilter)
        {
            string siteName = "http://myappserver.com/myname/";
            string webName = "Susite2";
            string listName = "Vendors List";
            string fieldTitle = "Title";
            List<Vendor> listVendor = new List<Vendor>();

            using (SPSite site = new SPSite(siteName))
            {
                using (SPWeb web = site.AllWebs[webName])
                //using (SPWeb web = site.OpenWeb())
                {
                   SPList list = web.Lists.TryGetList(listName);
                    if (list != null)
                    {
                        SPQuery query = new SPQuery();
                        query.ViewFields = "<FieldRef Name='Title' />" + "<FieldRef Name='ID'/>";
                        query.ViewFieldsOnly = true;
                        if (!string.IsNullOrEmpty(strFilter))
                            query.Query = "<Where><Eq><FieldRef Name='Title'/><Value Type='Text'>" + strFilter + "</Value></Eq></Where>";
                        SPListItemCollection items = list.GetItems(query);
                        if (items.Count > 0)
                        {
                            foreach (SPListItem item in items)
                            {
                                string title = Convert.ToString(item[fieldTitle]);
                                Vendor vendor = new Vendor();
                                vendor.Name = title;
                                vendor.VendorId = item.ID;
                                listVendor.Add(vendor);

                            }
                        }
                    }
                }
            }
                 return listVendor.OrderBy(a => a.Name).Select(a => a).ToArray();
    }

WEB.COnfig

<?xml version="1.0"?>
<configuration>

  <configSections>
    <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
        <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
          <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
          <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
          <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
          <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
        </sectionGroup>
      </sectionGroup>
    </sectionGroup>
  </configSections>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    <compilation debug="true">
      <assemblies>
        <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
      </assemblies>
    </compilation>
    <!--
        The <authentication> section enables configuration 
        of the security authentication mode used by 
        ASP.NET to identify an incoming user. 
    -->
    <authentication mode="Windows" />
    <!--
        The <customErrors> section enables configuration 
        of what to do if/when an unhandled error occurs 
        during the execution of a request. Specifically, 
        it enables developers to configure html error pages 
        to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
         <error statusCode="403" redirect="NoAccess.htm" />
         <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
    -->
    <pages>
      <controls>
        <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </controls>
    </pages>

    <httpHandlers>
      <remove verb="*" path="*.asmx"/>
      <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
    </httpHandlers>
    <httpModules>
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </httpModules>
  </system.web>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
                type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <providerOption name="CompilerVersion" value="v3.5"/>
        <providerOption name="WarnAsError" value="false"/>
      </compiler>
    </compilers>
  </system.codedom>
  <!-- 
      The system.webServer section is required for running ASP.NET AJAX under Internet
      Information Services 7.0.  It is not necessary for previous version of IIS.
  -->
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules>
      <remove name="ScriptModule" />
      <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </modules>
    <handlers>
      <remove name="WebServiceHandlerFactory-Integrated"/>
      <remove name="ScriptHandlerFactory" />
      <remove name="ScriptHandlerFactoryAppServices" />
      <remove name="ScriptResource" />
      <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
           type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
           type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </handlers>
  </system.webServer>
  <runtime>
    <assemblyBinding appliesTo="v2.0.05727" xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="SPListData.CustomDataListBehavior"
        name="SPListData.CustomDataList">
        <endpoint address="http://18.15.158.125:186/CustomDataList.svc" binding="wsHttpBinding" contract="SPListData.ICustomDataList">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SPListData.Service1Behavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
        <behavior name="SPListData.CustomDataListBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

ERROR SCREEN SHOT

enter image description here

8
  • How is the authentication on your ECT set up? technet.microsoft.com/en-us/library/… Commented Apr 6, 2014 at 17:20
  • BCS exists to surface data from other domains. It is acting as a proxy client and authenticates directly to the service it connects to. It can either use an account in the Secure Store to authenticate to the service or it can use pass-through which (generally) requires Kerberos. This is not a cross-domain issue. You need to configure the ECT to properly authenticate or the permissions on the list. Post a screen shot of your error. Commented Apr 6, 2014 at 17:26
  • Added the screen shot in my orginal issue Commented Apr 6, 2014 at 18:44
  • What's the authentication model BCS is using? Impersonate or Pass through? Commented Apr 6, 2014 at 18:57
  • Sorry i didnt get you.but if uou see my web.config Authentication mode is Windows Commented Apr 7, 2014 at 2:44

2 Answers 2

1

When using passthrough as the authentication scheme, you need to configure Kerberos Delegated Authentication for most real world scenarios.

When BCS attempts to use NTLM Windows authentication there is no mechanism for BCS to pass the current user's credentials on to the WCF service. This is why you get the authentication error, because your WCF service is rejecting AUTHORITY\ANONYMOUS LOGON.

When you use Kerberos, BCS is delegated the ability to pass your Kerberos ticket on to the WCF service. For Kerberos to work, all servers must be configured with the correct SPNs.

Here is a link to another question where I provide an answer to this same sort of scenario with BCS. Configuring Kerberos is not a trivial task. Here is the most important conceptual detail, though.

Understanding Passthrough Authentication
Passthrough authentication is in the Impersonation and Delegation authentication model. Setting the value of the AuthenticationMode element to Passthrough causes BCS to use the credentials of the current user to access the external system. Passthrough is simple to set up by selecting Connect with User’s Identity when configuring the external system connection in SharePoint Designer, as was shown in the walk-through earlier in this chapter. However, Passthrough authentication is unlikely to be useful in many situations because of limitations inherent in Windows authentication.

-Business Connectivity Services security overview (SharePoint Server 2010)

As I stated, to get by the limitations of NTLM, you need to configure Kerberos.

Your other option would be to create a service account in Active Directory, add it to the Secure Store and configure BCS to impersonate that account. You would then use SharePoint's authorization mechanism to control who has access to the External List.

Regarding basicHttpBinding

By default, the basicHttpBinding security mode is None. This default setting means that you do not have authentication and that neither transport nor message security is enabled. By enabling Windows authentication with TransportCredentialOnly, you will get authentication, but no message protection; this is similar to how an ASMX Web service works.

http://msdn.microsoft.com/en-us/library/ff648505.aspx

9
  • Hi Robert, I am using sharepoint 2010. I was able to fetch the web service methods in BCS using sharepoint designer. Howeever when i create an external list. i was not able to see the data in this list. It gives me an error Access Debied. I have given permissions to the user in central admin for the External content type but still it gives me an access denied. I suspect this could be because i am acessing the Webservice which is another domain. This user does not have permissions to do access it. Any help is much appreciated Commented Apr 6, 2014 at 16:59
  • I get the below error in the external list (The caller was not authenticated by the service) Commented Apr 6, 2014 at 17:16
  • OK, I did not understand your question, I think. You are simply asking how to surface a WCF service via BCS, correct? In this case, BCS is acting as a client. There is no cross-domain issue. I will delete this answer and get more clarification. Commented Apr 6, 2014 at 17:16
  • Yes, Actually i know how to surface the WCF service via BCS. But not sure if the web service is hosted on another domain. I am getting the above error when i access the external list Commented Apr 6, 2014 at 17:19
  • That does not matter. The BCS runtime is acting as a client directly to the service. Cross-Domain is not an issue here. The problem is with how the BCS runtime is authenticating to your WCF service. Commented Apr 6, 2014 at 17:21
0

The issue is resolved by making the below change in my web.config

wshttpbinindg to basicHttpbinidng( <endpoint address="18.15.158.125:186/CustomDataList.svc"; binding="basicHttpBinding" contract="SPListData.ICustomDataList">

Also one more change which i made was for my web service in IIS instead of Apppool account i have given windows user account.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.