Blogs

Call WCF Service (.NET) from SAP with UsernameToken and SSL
Wolfgang Bauer 
Business Card
Company: Osram Opto Semiconductors GmbH
Posted on Jul. 08, 2009 06:37 AM in Interoperability .NET

Subscribe.Subscribe
Print. Print
Permalink Permalink
Share

This blog describes how to call a WCF Service (.NET 3.5) from ABAP (ECC 6.0 EHP 3) with UsernameToken via SSL (https)

At the moment SAP supports only SOAP 1.1. Therefore the WCF Service must be configured with BasicHttpBinding like this:

 <basicHttpBinding>
    <binding name="Basic">
     <security mode="TransportWithMessageCredential">
       <message clientCredentialType="UserName"/>
     </security>
    </binding>
 </basicHttpBinding>

Configure the service interface to process all actions: (otherwise a mismatch error occurs):

   [OperationContract(Action = "*")]
      string HelloWorld(string value);

SAP Proxy Configuration in transaction SOAMANAGER:
image


image

Please also implement OSS-Note: 1354553 - Wrong namespace in password type attribute

Thanks to Martin Raepple (SAP AG) who has supported me.

Wolfgang Bauer   is a service architect for Osram Opto Semiconductors GmbH


Comment on this article
Comment on this weblog
Showing messages 1 through 9 of 9.

Titles Only Main Topics Oldest First

  • Hi
    2010-04-19 02:37:45 Wolfgang Bauer Business Card [Reply]

    Hi,


    1. Create your binding manually in the soamanager.
    2. Save the binding.
    3. Choose again edit binding.
    4. Now on the first tab other fields are available... ;-)


    regards

    • Still missing the listed fields
      2010-04-20 08:06:02 stefan seeland Business Card [Reply]

      Hi Wolfgang Bauer,


      our first attempts gone through the same steps. I tried it one time again like you propose.


      We still miss the listed fields on our development system and at our customers development system.


      If you are interested I will send you a screenshot and the corespending oss-message.


      regards Stefan Seeland

  • Problem to reproduce configuration
    2010-04-18 21:48:33 Wolfgang Bauer Business Card [Reply]

    Hi,


    I have created the binding manually in the soamanager.


    Here is the web.config:


    <?xml version="1.0"?>
    <!--
    Note: As an alternative to hand editing this file you can use the
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in
    machine.config.comments usually located in
    \Windows\Microsoft.Net\Framework\v2.x\Config
    -->
    <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>
    <customErrors mode="Off"></customErrors>
    <!--
    Set compilation debug="true" to insert debugging
    symbols into the compiled page. Because this
    affects performance, set this value to true only
    during development.
    -->
    <compilation debug="true">
    <assemblies>
    <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </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"/>
    </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>
    <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </modules>
    <handlers>
    <remove name="WebServiceHandlerFactory-Integrated"/>
    <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>
    <system.serviceModel>
    <bindings>
    <basicHttpBinding>
    <binding name="Basic">
    <security mode="TransportWithMessageCredential">
    <message clientCredentialType="UserName"/>
    </security>
    </binding>
    </basicHttpBinding>
    </bindings>
    <services>
    <service behaviorConfiguration="ServiceBehavior" name="WcfHelloWorld.Service1">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="Basic"
    bindingNamespace="http://osram-os.com/hello" contract="WcfHelloWorld.IService1" />
    </service>
    </services>
    <behaviors>
    <serviceBehaviors>
    <behavior name="ServiceBehavior">
    <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
    </behavior>
    </serviceBehaviors>
    </behaviors>
    <diagnostics performanceCounters="All" wmiProviderEnabled="true">
    <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="100000"/>
    </diagnostics>
    </system.serviceModel>
    <system.diagnostics>
    <sources>
    <source name="System.ServiceModel"
    switchValue="Information, ActivityTracing">
    <listeners>
    <add name="xml" />
    </listeners>
    </source>
    <source name="CardSpace">
    <listeners>
    <add name="xml" />
    </listeners>
    </source>
    <source name="System.IO.Log">
    <listeners>
    <add name="xml" />
    </listeners>
    </source>
    <source name="System.Runtime.Serialization">
    <listeners>
    <add name="xml" />
    </listeners>
    </source>
    <source name="System.IdentityModel">
    <listeners>
    <add name="xml" />
    </listeners>
    </source>
    </sources>


    <sharedListeners>
    <add name="xml"
    type="System.Diagnostics.XmlWriterTraceListener"
    initializeData="c:\tmp\Traces5.svclog" />
    </sharedListeners>
    </system.diagnostics>


    </configuration>


    regards

    • Problem to reproduce configuration
      2011-08-18 17:57:54 pradeep r Business Card [Reply]

      Hi,
      I'm having same issue in our CRM system. I used your web.config file and getting error in Method: IF_SIDL_DESERIALIZER~DESERIALIZE of program CL_SIDL_DESERIALIZER==========CP. Reason is this method check for url http://schemas.xmlsoap.org/wsdl/ in the file. I did following steps.
      1.From SE80 created Enterprise Services using WSDL file.
      2.In SOAMANAGER select my consumer proxy.
      3.Created Logical port ZXYZ by selecting WSDL based configuration and gave web.config.
      If I give original WSDL I'm getting only User name and password option.


      My Actual Requirement is WSDL which I consume need password type as Passwordtext.


      Now if use original wsdl and execute the proxy I getting login error. Same error which get in SOAPUi if I got use passwordtext. When checked the soapui Soap header is formed like below


      <soapenv:Header>
      <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <wsse:Username>USERNAME</wsse:Username>
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">PASSWORD</wsse:Password>
      <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">5oHK2KjEop8a6OPsl3pw6Q==</wsse:Nonce>
      <wsu:Created>2011-08-17T17:58:50.068Z</wsu:Created>
      </wsse:UsernameToken>
      </wsse:Security>
      </soapenv:Header>


      Can you suggest me how password type as passwordtext.


      Thanks in advance

    • Problem to reproduce configuration
      2010-04-20 09:04:19 Mathias Essenpreis SAP Employee Business Card [Reply]

      Unfortunately the WSDL that will be generated out of Wolfgang's example with the BasicHTTPBinding does use WS Security Policy 1.1. Creating a logical port out of this WSDL will throw an error in SOAMANAGER.


      SAP Web Service Consumers only support WS Security Policy 1.2. Net 3.5 can generate such WSDLs when using a CustomBinding with option messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10


      I attached a web.config that will generate a working wsdl that can be shown when opening http://localhost:8080/MEX?wsdl



      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
      <system.serviceModel>
      <behaviors>
      <serviceBehaviors>
      <behavior name="NewBehavior">
      <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/MEX"
      httpsGetEnabled="true" httpsGetUrl="https://localhost:8081/MEX" />
      <!--serviceCredentials>
      <serviceCertificate findValue="WSS ABAP" x509FindType="FindBySubjectName" />
      </serviceCredentials-->
      </behavior>
      </serviceBehaviors>
      </behaviors>
      <services>
      <service behaviorConfiguration="NewBehavior" name="ConsoleApplication1.HelloService">
      <endpoint address="TS_AMI" binding="customBinding" bindingConfiguration="SSL_UsernameToken_CustomBinding"
      name="SSL_UN" contract="ConsoleApplication1.HelloService" />
      <host>
      <baseAddresses>
      <add baseAddress="https://localhost:8081" />
      </baseAddresses>
      </host>
      </service>
      </services>
      <bindings>
      <customBinding>
      <binding name="SSL_UsernameToken_CustomBinding">
      <textMessageEncoding />
      <security authenticationMode="UserNameOverTransport" messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
      <secureConversationBootstrap />
      </security>
      <httpsTransport />
      </binding>
      </customBinding>
      </bindings>
      <client>
      <remove contract="IMetadataExchange" name="sb" />
      </client>
      </system.serviceModel>
      </configuration>

      • Problem to reproduce configuration
        2010-04-20 10:35:02 stefan seeland Business Card [Reply]

        Hi Mathias Essenpreis,
        Thanks for your configuration!


        The binding creation stops after submitting the wsdl with the error message


        Fehler: Uninistanziertes Objekt subject sidl service in Methode IF_SRT_WSP_CONFIG_SIDL CREATE_CLNT_CFG_FROM_WSDL_D der Klasse CL_SRT_WSP_CONFIG_SIDL


        The same error was displayed in the past with the wsdl wich was generated with Wolfgang's configurtion but the http-version works.


        The generated Wsdl:


        <?xml version="1.0" encoding="utf-8" ?>
        - <wsdl:definitions name="HealtObjectService" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
        - <wsp:Policy wsu:Id="https_policy">
        - <wsp:ExactlyOne>
        - <wsp:All>
        - <sp:TransportBinding xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        - <wsp:Policy>
        - <sp:TransportToken>
        - <wsp:Policy>
        <sp:HttpsToken />
        </wsp:Policy>
        </sp:TransportToken>
        + <sp:AlgorithmSuite>
        - <wsp:Policy>
        <sp:Basic256 />
        </wsp:Policy>
        </sp:AlgorithmSuite>
        - <sp:Layout>
        - <wsp:Policy>
        <sp:Strict />
        </wsp:Policy>
        </sp:Layout>
        <sp:IncludeTimestamp />
        </wsp:Policy>
        </sp:TransportBinding>
        - <sp:SignedEncryptedSupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        - <wsp:Policy>
        - <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
        - <wsp:Policy>
        <sp:WssUsernameToken10 />
        </wsp:Policy>
        </sp:UsernameToken>
        </wsp:Policy>
        </sp:SignedEncryptedSupportingTokens>
        - <sp:Wss10 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        - <wsp:Policy>
        <sp:MustSupportRefKeyIdentifier />
        <sp:MustSupportRefIssuerSerial />
        </wsp:Policy>
        </sp:Wss10>
        - <sp:Trust13 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        - <wsp:Policy>
        <sp:MustSupportIssuedTokens />
        <sp:RequireClientEntropy />
        <sp:RequireServerEntropy />
        </wsp:Policy>
        </sp:Trust13>
        <wsaw:UsingAddressing />
        </wsp:All>
        </wsp:ExactlyOne>
        </wsp:Policy>
        - <wsdl:types>
        - <xsd:schema targetNamespace="http://tempuri.org/Imports">
        <xsd:import schemaLocation="https://<mylittlesecret>:8443/WebSetupDataService/HealthObjectsService.svc?xsd=xsd0" namespace="http://tempuri.org/" />
        <xsd:import schemaLocation="https://<mylittlesecret>:8443/WebSetupDataService/HealthObjectsService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
        <xsd:import schemaLocation="https://<mylittlesecret>:8443/WebSetupDataService/HealthObjectsService.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/WcfServiceLibraryCED" />
        </xsd:schema>
        </wsdl:types>
        - <wsdl:message name="IHealthobject_SubmitValue_InputMessage">
        <wsdl:part name="parameters" element="tns:SubmitValue" />
        </wsdl:message>
        - <wsdl:message name="IHealthobject_SubmitValue_OutputMessage">
        <wsdl:part name="parameters" element="tns:SubmitValueResponse" />
        </wsdl:message>
        - <wsdl:portType name="IHealthobject">
        - <wsdl:operation name="SubmitValue">
        <wsdl:input wsaw:Action="http://tempuri.org/IHealthobject/SubmitValue" message="tns:IHealthobject_SubmitValue_InputMessage" />
        <wsdl:output wsaw:Action="http://tempuri.org/IHealthobject/SubmitValueResponse" message="tns:IHealthobject_SubmitValue_OutputMessage" />
        </wsdl:operation>
        </wsdl:portType>
        - <wsdl:binding name="https" type="tns:IHealthobject">
        <wsp:PolicyReference URI="#https_policy" />
        <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
        - <wsdl:operation name="SubmitValue">
        <soap12:operation soapAction="http://tempuri.org/IHealthobject/SubmitValue" style="document" />
        - <wsdl:input>
        <soap12:body use="literal" />
        </wsdl:input>
        - <wsdl:output>
        <soap12:body use="literal" />
        </wsdl:output>
        </wsdl:operation>
        </wsdl:binding>
        - <wsdl:service name="HealtObjectService">
        - <wsdl:port name="https" binding="tns:https">
        <soap12:address location="https://<mylittlesecret>:8443/WebSetupDataService/HealthObjectsService.svc/HealthService" />
        - <wsa10:EndpointReference>
        <wsa10:Address>https://<mylittlesecret>:8443/WebSetupDataService/HealthObjectsService.svc/HealthService</wsa10:Address>
        </wsa10:EndpointReference>
        </wsdl:port>
        </wsdl:service>
        </wsdl:definitions>



        regards Stefan Seeland

    • Problem to reproduce configuration
      2010-04-19 02:29:41 stefan seeland Business Card [Reply]

      Hi,


      thanks for the detailed information about your service. I also create the binding by manual configuration, but i do not have the same options in the soamanager like you. I miss the whole Transport and Authentication options you show in your first screenshot. The options I have here on an EHP 4 are the Autheticationmechanism (User-ID and Password or Sap-Authenticationticket). I translated the text from the options from a german system, so maybe it is not exact the same name in your system.


      In the transport settingstab I miss here your fields ESR Target Client and WSDL Style.


      Do you know any reason why our soamanagers differ?


      By the way:
      I read http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/e0ecb76a-2f70-2a10-8bb6-bf5d4f1fb750?QuickLink=index&overridelayout=true where Martin Raepple writes about problems with basicHttpBinding.

  • Problem to reproduce configuration
    2010-04-16 08:26:25 stefan seeland Business Card [Reply]

    Hi Wolfgang Bauer,
    I can not reproduce your setting. How did you create the binding in the soamanger? Did you configure by loading the wsdl or by manual configuration?


    Was the service hosted in IIS? Can you provide the used web.config or app.config?


    I ask you this question because we get a parsing error at creating the binding with the wsdl of an IIS-Hosted Service.


    This services works with Java.

    • Problem to reproduce configuration
      2010-04-20 09:16:58 Mathias Essenpreis SAP Employee Business Card [Reply]

      Hi Stefan,
      in my reply post to Wolfgang's web.config I attached a web.config that will generate a compatible WSDL.


      Please use the WSDL based option for creating your logical port.


      After importing the WSDL you should only be asked for the username and a password for the WS Call. So the security tab differs from the UI Wolfgang posted. It only shows the username and the password field.


      Regards,
      Mathias


Showing messages 1 through 9 of 9.