Search code examples
wcfwifsaml-2.0ws-securitywsfederationhttpbinding

<security> tag requirement in consuming WCF with SAML token and using Federation binding


we have STS service whihc provides SAML token within the organization for security reasons all apps should get this token. I am buiulding a WCF service which should accept a SAML token and validate the same before serving the request.

So far I have setup a Federationbinding [not sure though its intended requirement as my service serves only interal/intranet apps within the firewall. I managed to to hit my WCF by using SOAP UI and get the response as well while debugging. but, the strange thing is in the request I had to mask my SAML under security tag else it never works; I am wondering ius there any workaroun for this or this is intended use. as the Java clients will be consuming my WCF service.

    <?xml version="1.0" ?>
<configuration>
  <configSections>
    <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.30319.17929, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
  </configSections>
  <appSettings>
    <add key="EncryptionCertificateName" value="xxxx" />
    <add key="AssertionSignatureCertificateName" value="xxxx" />
    <add key="EnablePerformanceLog" value="false" />
    <add key="Logging.Level" value="0" />
    <add key="Logging.Active" value="True" />
  </appSettings>
  <runtime>
    <gcServer enabled="true" />
    <generatePublisherEvidence enabled="false" />
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.web>
    <compilation debug="true" targetFramework="4.5" optimizeCompilations="true" batch="true" maxConcurrentCompilations="8" />
    <httpRuntime targetFramework="4.5" minFreeThreads="10" minLocalRequestFreeThreads="10" requestValidationMode="2.0" />
  </system.web>
  <system.net>
    <defaultProxy enabled="false">
      <proxy usesystemdefault="False" bypassonlocal="True" autoDetect="False" />
    </defaultProxy>
    <connectionManagement>
      <add address="*" maxconnection="5000" />
    </connectionManagement>
  </system.net>
  <system.serviceModel>
    <diagnostics performanceCounters="All">
      <messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
      <endToEndTracing propagateActivity="true" messageFlowTracing="true" />
    </diagnostics>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceCredentials useIdentityConfiguration="true" />
          <serviceAuthorization principalPermissionMode="Always" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
      <serviceActivations>
        <add relativeAddress="Service.svc" service="XX.XXX.BusinessService.Service.VaultService" factory="XX.XXXX.BusinessService.Service.WcfServiceFactory" />
      </serviceActivations>
    </serviceHostingEnvironment>
    <bindings>
      <ws2007FederationHttpBinding>
        <binding name="ws2007Binding">
          <security mode="TransportWithMessageCredential">
            <message establishSecurityContext="false" issuedKeyType="BearerKey" issuedTokenType="urn:oasis:names:tc:SAML:2.0:assertion" negotiateServiceCredential="false" />
          </security>
        </binding>
      </ws2007FederationHttpBinding>

    </bindings>
    <services>
      <service name="XX.XXXX.BusinessService.Service.Service">
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost/XX.XXX.BusinessService.Service/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007Binding" contract="XX.XXXX.Contract.Service.ServiceContract.IService" />
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="false" />
    <httpProtocol>
      <customHeaders>
        <add name="X-Content-Type-Options" value="nosniff" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.identityModel>
    <identityConfiguration saveBootstrapContext="true">
      <!--<audienceUris>
        <add value="VaultService.svc"/>
      </audienceUris>-->
      <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <trustedIssuers>
          <add name="XX-XX-XX" thumbprint="XXX" />
        </trustedIssuers>
      </issuerNameRegistry>
      <securityTokenHandlers>
        <remove type="System.IdentityModel.Tokens.Saml2SecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <add type="XX.XXX.Extension.Security.MySecurityTokenHandler, XXX.XXX.Extension" />
      </securityTokenHandlers>
      <claimsAuthenticationManager type="XX.XXXX.Extension.Security.ClaimsAuthenticationManager, XX.XXXX.Extension" />
    </identityConfiguration>
  </system.identityModel>
  <location path="health-check.axd">
    <system.web>
      <authorization>
        <allow users="?" />
      </authorization>

    </system.web>
    <system.webServer>
      <validation validateIntegratedModeConfiguration="false" />

      <httpErrors existingResponse="PassThrough" />
    </system.webServer>
  </location>
</configuration>

the sample request that works from SOAP UI:

    <soap:Envelope xmlns:soa="http://XXX.com.au/soa" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:ing="http://schemas.datacontract.org/2004/07/XXX.Contract.Vault.DataContract" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <soap:Header>
  <a:Action s:mustUnderstand="1">http://tempuri.org/IService1/DoWork</a:Action>
  <a:MessageID>urn:uuid:b48f6fa8-f5f2-48d8-a06b-1a202c71ed30</a:MessageID>
  <a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
  </a:ReplyTo>
  <a:To s:mustUnderstand="1"></a:To>
  <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
  <u:Timestamp u:Id="_0">
 <u:Created>2015-10-26T10:47:54.721Z</u:Created>
 <u:Expires>2015-10-26T10:53:54.721Z</u:Expires>
  </u:Timestamp>
<Assertion ID="_e058ad04-1d5e-47cf-9fbc-d65aecfaf9ef" IssueInstant="2015-10-24T06:22:37.086Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">...</Assertion>
  </o:Security>
  </soap:Header>
   <soap:Body>
      ....
 .....
   </soap:Body>
</soap:Envelope>

you see that here the SAML assertion included under tag, if I remove this then service will not work says security message header not present error.


Solution

  • this seems to be security tag required since I am using federation binding and Identity model for tokens. anyway java service was able to consume the service after they wrap token in genrericXMLtoken which generates the security tag.