# Wednesday, November 15, 2006

I've come a long way since the last issue, and I think I have most of that stuff worked out.  Now the problem is that what I really need is to be able to use the Dual Http binding, in conjunction with an STS to provide the SAML tokens.  I have it working fine (with Dual binding) as long as I issue the token myself and attach it using ClientCredentials.

The server side binding looks like this

 

        <behaviors>

            <serviceBehaviors>

                <behavior name="tokenBehavior">

                    <serviceCredentials>

                        <clientCertificate>

                            <certificate findValue="CN=VoyagerClient" />

                            <authentication certificateValidationMode="PeerOrChainTrust"

                                revocationMode="NoCheck" />

                        </clientCertificate>

                        <serviceCertificate findValue="CN=VoyagerServer" />

                        <issuedTokenAuthentication allowUntrustedRsaIssuers="true">

                            <knownCertificates>

                                <add findValue="CN=VoyagerSecureTokenService" storeLocation="LocalMachine"

                                    storeName="My" x509FindType="FindBySubjectDistinguishedName" />

                            </knownCertificates>

                        </issuedTokenAuthentication>

                    </serviceCredentials>

                </behavior>

            </serviceBehaviors>

        </behaviors>

        <bindings>

            <wsDualHttpBinding>

                <binding name="tokenBinding" clientBaseAddress="http://localhost:8897/client">

                    <security>

                        <message clientCredentialType="IssuedToken" />

                    </security>

                </binding>

            </wsDualHttpBinding>

        </bindings>

the client side binding like so

 

        <behaviors>

            <endpointBehaviors>

                <behavior name="tokenBehavior">

                    <clientCredentials>

                        <clientCertificate findValue="CN=VoyagerClient" storeLocation="LocalMachine" />

                        <serviceCertificate>

                            <defaultCertificate findValue="CN=VoyagerServer" storeLocation="LocalMachine" />

                            <authentication certificateValidationMode="PeerOrChainTrust"

                                revocationMode="NoCheck" />

                        </serviceCertificate>

                    </clientCredentials>

                </behavior>

            </endpointBehaviors>

        </behaviors>

        <bindings>

            <wsDualHttpBinding>

                <binding name="tokenBinding" clientBaseAddress="http://localhost:8897/client">

                    <security>

                     <message clientCredentialType="IssuedToken"/>

                    </security>

                </binding>

            </wsDualHttpBinding>

        </bindings>

 On the client side, I'm using the SamlClientCredentials from the SamlTokenProvider sample, and attaching it to the outgoing endpoint.

 

SamlClientCredentials cred = new SamlClientCredentials();

cred.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectDistinguishedName, "CN=VoyagerClient");

 

cred.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectDistinguishedName, "CN=VoyagerSecureTokenService");

            cred.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.

     X509CertificateValidationMode.PeerOrChainTrust;

cred.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;

 

IList<Claim> claims = new List<Claim>();

claims.Add(Claim.CreateNameClaim("Fred"));

ClaimSet claimset = new DefaultClaimSet(claims);

cred.Claims = claimset;

 

CallBack callback = new CallBack();

InstanceContext ic = new InstanceContext(callback);

HelloWorldClient client = new HelloWorldClient(ic);

client.ChannelFactory.Endpoint.Behaviors.Remove(typeof(ClientCredentials));

client.ChannelFactory.Endpoint.Behaviors.Add(cred);

This all works like I would expect, and I get properly authorized on the server side.  The only catch here is that since I'm signing the SAML token with a cert I created myself, I have to set the certificateValidationMode for the issuedTokenAuthorization bit on the server side, which sadly isn't supported through the config file, so I have to tweak the ServiceHost myself.

 

myServiceHost = new ServiceHost(typeof(HelloService), baseAddress);

 

myServiceHost.Credentials.IssuedTokenAuthentication.

CertificateValidationMode =

X509CertificateValidationMode.PeerOrChainTrust;

 

myServiceHost.Credentials.IssuedTokenAuthentication.RevocationMode = X509RevocationMode.NoCheck;

 

 

myServiceHost.Open();

Not too much trouble, but unfortunate.  Means things will be a little more interesting when it's hosted in IIS. 

So, that all works, but what I really need is for it to ask an STS for the correct token rather than creating one myself. 

I was hoping that putting this in my clientCredentials on the client side would do it

 

<issuedToken>

   <localIssuer address="http://localhost:9001/sts" binding="wsHttpBinding" bindingConfiguration="" />

</issuedToken>

but it doesn't seem to. I'm assuming that's behavior that's built into the wsFederationHttpBinding, and not in wsDualHttpBinding. I'm hoping that I won't have to make the call to the STS myself, but as a last resort, that'll do...
Wednesday, November 15, 2006 2:34:20 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |