Question

Currently I can establish a WCF channel with an IssuedToken by first establishing the security token from the STS with a certificate credential via the WS-Trust endpoint and then calling CreateChannelWithIssuedToken() on the channel factory. See How to specify a certificate as the credentials for a wsTrustChannel with Thinktecture IdentityServer

However, instead of doing this:

var securityToken = GetMeASecurityTokenFromTheSts();
var myServiceChannelFactory = new ChannelFactory<IMyService>();
myServiceChannelFactory.CreateChannelWithIssuedToken(securityToken);

I'd ideally like to just do this (and have the issuer of the security token automatically issue a token based on the passed certificate).

var myClient = new MyServiceClient();

My question is - can a binding be configured something like the following to specify that the ThinkTecture IdentityServer STS is the Issuer for security tokens?

<bindings>
  <ws2007FederationHttpBinding>
    <binding name="WS2007FederationHttpBinding">
      <security mode="TransportWithMessageCredential">
        <message issuedKeyType="BearerKey" issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
          <issuer address="https://mymachine/myidserver/issue/wstrust/mixed/certificate">
            <identity>
              <certificateReference storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="XXXXXXXXXXXXXXXXXXXXXXXXX"/>
            </identity>
          </issuer>
          <issuerMetadata address="https://mymachine/myidserver/FederationMetadata/2007-06/FederationMetadata.xml" />
          <tokenRequestParameters>
            <trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
              <trust:TokenType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</trust:TokenType>
              <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:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
                xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
                <wsid:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
                  xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
              </trust:Claims>
              <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>
</bindings>

if so - I'm having a lot of trouble configuring this part of the binding:

<issuer address="https://mymachine/myidserver/issue/wstrust/mixed/certificate">
    <identity>
        <certificateReference storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="XXXXXXXXXXXXXXXXXXXXXXXXX"/>
    </identity>
</issuer>

My main area of confusion is this: The issuer config element seems to encapsulate the binding, behavior and endpoint all in one element. The binding can be configured - and clearly has to as the above issuer element complains about not having a binding configured. But how do you specify the SSL certificate for the issuer channel as this is a behavior configuration thing, and there doesn't appear to be any way to set the behavior for the issuer endpoint.

Was it helpful?

Solution

Using the config only approach has indeed the problem of binding the token lifetime to the proxy lifetime. In addition the realm (appliesTo) you configure in IdentityServer has to match the physical URL of the WCF service. Both is IMO not practical and the "manual" WSTrustChannelFactory approach is much more recommended.

That said - svcutil (or "Add Service Reference") creates all the necessary client configuration for you. You just need to make sure that you point to IdentityServer's MEX endpoint in the WCF service configuration, e.g.:

<bindings>
      <ws2007FederationHttpBinding>
        <binding>
          <security mode="TransportWithMessageCredential">
            <message establishSecurityContext="false"
                     issuedKeyType="BearerKey">
              <issuerMetadata address="https://identity.thinktecture.com/idsrvsample/issue/wstrust/mex" />
            </message>
          </security>
        </binding>
      </ws2007FederationHttpBinding>
    </bindings>

https://github.com/thinktecture/Thinktecture.IdentityServer.v2/blob/master/samples/MVC%20and%20WCF%20RP%20(SAML)/Web/Web.config

...and the MEF issue is fixed btw.

OTHER TIPS

You can set binding configuration for issuer. Use of certificate will be set on MyServiceClient behaviour. I have not tested this configuration but it could work.

Here is your modified configuration

<bindings>
    <ws2007FederationHttpBinding>
        <binding name="WS2007FederationHttpBinding">
            <security mode="TransportWithMessageCredential">
                <message issuedKeyType="BearerKey" issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
                    <issuer address="https://mymachine/myidserver/issue/wstrust/mixed/certificate" binding="ws2007HttpBinding" 
                  bindingConfiguration="issuerBindingConfig">
                    </issuer>
                    <issuerMetadata address="https://mymachine/myidserver/FederationMetadata/2007-06/FederationMetadata.xml" />
                    <tokenRequestParameters>
                        <trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
                            <trust:TokenType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</trust:TokenType>
                            <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:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
            xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
                                <wsid:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
              xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
                            </trust:Claims>
                            <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>
        <!--SWACA RAWS Client authentication binding-->
        <binding name="issuerBindingConfig">
            <security mode="TransportWithMessageCredential">
                <transport clientCredentialType="None" />
                <message clientCredentialType="Certificate" establishSecurityContext="false" />
            </security>
        </binding>
    </ws2007HttpBinding>
</bindings>


<endpointBehaviors>
    <behavior name="MyServiceClient">
        <clientCredentials supportInteractive="false">
            <clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="XXXXXXXXXXXXXXXXXXXXXXXXX" />
        </clientCredentials>
    </behavior>
</endpointBehaviors>

However please keep in mind that if you do that then each new MyServiceClient() will practically request a token from STS. When we used this approach in our system we had some MEF threadsafety problems with IdentityServer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top