# Wednesday, 15 November 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, 15 November 2006 14:34:20 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 06 November 2006

I've been having a lot of trouble with Rhapsody ever since installing IE 7.  It got significantly better after the official release of IE 7, but I was still having the Rhapsody client crash 5-6 times a day, which is very frustrating.  Frustrating enough that I was considering just giving it up. 

The redemption came in the form of their new online version of the player, which runs hosted inside a browser.  It's less fully featured than the offline client, but it's been totally stable, runs well inside Firefox 2.0, and generally hasn't given me any trouble at all.  For now, I'm willing to forego the extra features for a player which really works.  It's even supposed to work in Linux, which means I might finally upgrade my kitchen PC from W2K to Ubuntu.  We can only hope.

You can run the online player by going to http://www.rhapsody.com.  I've had a lot of trouble navigating Rhapsody related stuff, since it's spread across www.rhapsody.com, www.listen.com, and various bits and pieces of www.real.com.  None of them seem to have the same information or links, so it can be hard to find what you are looking for.  I'm willing to accept this as the price I pay for reasonably prices access to tons of music.

Monday, 06 November 2006 13:19:27 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, 03 November 2006

I've started working on building an STS for use in some new product scenarios, and using the wsFederationHttpBinding, and I totally get how that works if the user is supposed to send their username and password to the STS to be authorized. 

 

I'm talking to the STS with a binding like so

 

      <customBinding>

        <binding name="UsernameBinding">

          <security authenticationMode="UserNameForCertificate" requireDerivedKeys="true" messageProtectionOrder="SignBeforeEncryptAndEncryptSignature" requireSecurityContextCancellation="false" requireSignatureConfirmation="false">

            <secureConversationBootstrap/>

          </security>

          <httpTransport/>

        </binding>

      </customBinding>

and in the client (in this case a web app) I set the credentials thusly

 

ChannelFactory<IHelloWorldChannel> factory =

new ChannelFactory<IHelloWorldChannel>("clientendpoint");

factory.Credentials.UserName.UserName = "MyUser";

factory.Credentials.UserName.Password = "MyPassword";

 

 

IHelloWorldChannel helloWorldService = factory.CreateChannel();

 

string response = helloWorldService.HelloWorld("John Doe");

That works great.  I validate the users credentials with a custom UserNamePasswordValidator, and everyone is happy.  Works just like it's supposed to. 

What I'd also like to be able to support is self-issued CardSpace cards.  I envision it working like this

Which should mean (again, as I envision it working) that my STS is configured like

 

      <wsHttpBinding>

        <binding name="stsInfoCard">

          <security mode="Message">

            <message clientCredentialType="IssuedToken" establishSecurityContext ="false"/>

          </security>

        </binding>

      </wsHttpBinding>

The part I don't get is what's the equivalent of setting the username and password on the ChannelFactory for CardSpace cards?  It seems like there should be some way of presenting the CardSpace token to the STS and having the rest of it work.

Is this just not possible, or am I missing something?  Is there another way to make this work?  I can get the CardSpace token just fine as far as the web server, but I don't know where to go from there.

Friday, 03 November 2006 15:27:57 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, 01 November 2006

My ADAM woes are largely over, and now I'm on to implementing an STS and getting some federated trust scenarios working.  Wish me luck, and I'll soon have more to report...

Wednesday, 01 November 2006 11:14:24 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

I'll be teaching C# at the CAPITAL Center (Portland/Beaverton) campus of OIT next term (CST 346P), so if you or someone you love is looking to learn more about C#, run don't walk to OIT's web site to sign up.

I'm in the midst of co-teaching the first part of the senior project class right now, and having quite a bit of fun at it.  It's very interesting to see how people approach their senior projects, and fun to talk about all aspects of software development in just 10 weeks. :-)

Wednesday, 01 November 2006 11:13:15 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |