How to use IssuedToken in a client with a WCF Service Reference

dapug picture dapug · Feb 13, 2013 · Viewed 7.8k times · Source

I have a WinForms app with a Service Reference generated from a WCF service that uses WS2007FederationHttpBinding. I can't understand why the following is not working.

My WinForms app is calling a WCF service that is using Thinktecture.IdentityServer, set up to handle BearerKey type tokens.

From my client I simply acquire a valid access token, and make this call:

    private static void CallServiceReference(SecurityToken token)
    {
        ServiceReference1.ClaimsServiceContractClient svcRef = new ServiceReference1.ClaimsServiceContractClient();

        svcRef.ChannelFactory.Credentials.SupportInteractive = false;
        svcRef.ChannelFactory.CreateChannelWithIssuedToken(token);
        var claims = svcRef.GetClaims(); 
    }

Here is the winforms client app.config for the service reference:

<system.serviceModel>
      <bindings>
              <ws2007FederationHttpBinding>
                      <binding name="WS2007FederationHttpBinding_ClaimsServiceContract">
                              <security mode="TransportWithMessageCredential">
                                      <message establishSecurityContext="false" issuedKeyType="BearerKey">
                                              <issuer address="https://identity.MyCo.com/issue/wsfed" binding="ws2007HttpBinding"
                                                      bindingConfiguration="https://identity.MyCo.com/issue/wstrust/mixed/username" />
                                              <issuerMetadata address="https://identity.MyCo.com/issue/wstrust/mex" />
                                              <tokenRequestParameters>
                                                      <trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
                                                              <trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
                                                              <trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
                                                              <trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
                                                      </trust:SecondaryParameters>
                                              </tokenRequestParameters>
                                      </message>
                              </security>
                      </binding>
              </ws2007FederationHttpBinding>
              <ws2007HttpBinding>
                      <binding name="https://identity.MyCo.com/issue/wstrust/mixed/username">
                              <security mode="TransportWithMessageCredential">
                                      <transport clientCredentialType="None" />
                                      <message clientCredentialType="IssuedToken" establishSecurityContext="false" />
                              </security>
                      </binding>
              </ws2007HttpBinding>
      </bindings>
      <client>
              <endpoint address="https://roadie/WebTest/service.svc" binding="ws2007FederationHttpBinding"
                      bindingConfiguration="WS2007FederationHttpBinding_ClaimsServiceContract"
                      contract="ServiceReference1.ClaimsServiceContract" name="WS2007FederationHttpBinding_ClaimsServiceContract" />
      </client>
  </system.serviceModel>

When I try and execute the service call (svcRef.GetClaims()) I get this error:

"The address of the security token issuer is not specified. An explicit issuer address must be specified in the binding for target 'https://identity.MyCo.com/issue/wsfed' or the local issuer address must be configured in the credentials."

This error is lame, and confusing, seems how there is an issuer specified in the config!

Lastly, I know the WCF service and Identity service are valid because this all works fine using a custom ChannelFactory, also using this exact same method to apply the token:

var channel = factory.CreateChannelWithIssuedToken(token);

But my requirement is to use the generated ServiceReference. :(

Answer

maland picture maland · Mar 26, 2014

You should use the created channel like this:

private static void CallServiceReference(SecurityToken token)
{
    ServiceReference1.ClaimsServiceContractClient svcRef = 
        new ServiceReference1.ClaimsServiceContractClient();

    svcRef.ChannelFactory.Credentials.SupportInteractive = false;
    var svcChannel = svcRef.ChannelFactory.CreateChannelWithIssuedToken(token);
    var claims = svcChannel.GetClaims();
}