# Monday, December 11, 2006

One of the (many) issues I encountered in creating a duplex http binding with IssuedToken security (details here) was that when using a duplex contract, the client has to open a "server" of its own to receive the callbacks from the "server" part of the contract.  Unfortunately, there are a couple of fairly critical settings that you'd want to change for that client side "server" that aren't exposed via the configuration system, and have to be changed via code.

One that was really causing me problems was that for each duplex channel I opened up (and for one of our web apps, that might be 2-3 per ASP.NET page request) I had to provide a unique BaseClientAddress for each channel, which quickly ran into problems with opening too many ports (a security hassle) and insuring uniqueness of the URI's (a programming hassle).  Turns out that you can ask WCF to create unique addresses for you, specific to your chosen transport in their method of uniqueness.  However, you make that request by setting the ListenUri and ListenUriMode properties on the ServiceEndpoint (or the BindingContext).  For the client-side "server" part of a duplex contract, that turns out to be one of those settings that isn't exposed via configuration (or much of anything else, either). 

Luckily, I found an answer in the good works of Nicholas Allen (yet again).  He mentioned that you could set such a property on the BindingContext for the client side of a duplex contract.  Not only that, but Mike Taulty was good enough to post a sample of said solution. 

There's a great summary of the solution here, but to summarize even more briefly, you have to create your own BindingElement, and inject it into the binding stack so that you can grab the BindingContext as it hastens past.  Now I'm setting the ListenUri base address on a specific port, and asking WCF to do the rest by unique-ifying the URI.  Not only do I not have to keep track of them myself, but I can easily control which ports are being used on the client side, which makes both IT and Security wonks really happy.

Monday, December 11, 2006 11:02:53 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, December 05, 2006

On Scott's recommendation, Vikki and I got Brick from Netflix and watched it a few days back.  Then watched it again. 

If you like film noir, Brick is a no-brainer. 

The basic vision of the film (and it won a Sundance prize for originality of vision) is that of a classic Hammet-esque noir film, but set in a Southern Californian High School.  No, really.  And it's brilliant.  The actors all obviously got it.  There's nothing farcical or comic about the performances.  They all believe in the vision.  Which isn't to say that there aren't funny moments (such as the hero meeting with the most dangerous drug dealer in town while his Mom serves them juice and cookies) but they are funny as part of the plot, not because of the aesthetic of the film. 

Solid performances all around, and some great dialog.  The dialog is heavily spiked with both gumshoe and pseudo-modern-teen argot, so turning on the subtitles helps follow the story the first time through. 

There's a lot of depth here, especially for a directorial debut, and I think this is a film I'll go back and watch over and over again.

Tuesday, December 05, 2006 4:13:57 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

This took me WAY longer to figure out that either a) it shoudl have or b) I had hoped it would.  I finally got it working last week though.  I now have my client calling the server via a Dual Contract using IssuedToken security (requires a SAML token), said token being obtained from an STS written by me, which takes a custom token from the client for authentication. 

On the plus side, I know a whole bunch more about the depths of the ServiceModel now than I did before. :-)

It turns out (as far as I can tell) that the binding I needed for client and server cannot be described in a .config file, and must be created in code.  That code looks like this on the server


public static Binding CreateServerBinding(Uri baseAddress, Uri issuerAddress)



    CustomBinding binding = new CustomBinding();

    IssuedSecurityTokenParameters issuedTokenParameters =

        new IssuedSecurityTokenParameters();

    issuedTokenParameters.IssuerAddress = new EndpointAddress(issuerAddress);

    issuedTokenParameters.IssuerBinding = CreateStsBinding();

    issuedTokenParameters.KeyType = SecurityKeyType.SymmetricKey;

    issuedTokenParameters.KeySize = 256;


        = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1";


    SecurityBindingElement security

        = SecurityBindingElement.CreateIssuedTokenBindingElement(issuedTokenParameters);


    binding.Elements.Add(new CompositeDuplexBindingElement());

    binding.Elements.Add(new OneWayBindingElement());

    binding.Elements.Add(new TextMessageEncodingBindingElement());

    binding.Elements.Add(new HttpTransportBindingElement());


    return binding;


and essentially the same on the client, with the addition of setting the clientBaseAddress on the CompositeDuplexBindingElement.

This works just fine, getting the token from the STS under the covers and then calling the Dual Contract server interface with the token. 

I ended up with a custom binding to the STS itself, mostly because I needed to pass more credentials than just user name and password.  So the STS binding gets created thusly:


public static Binding CreateStsBinding()


    Binding binding = null;


    SymmetricSecurityBindingElement messageSecurity

        = new SymmetricSecurityBindingElement();



     SignedEncrypted.Add(new VoyagerToken.VoyagerTokenParameters());


    X509SecurityTokenParameters x509ProtectionParameters

        = new X509SecurityTokenParameters( X509KeyIdentifierClauseType.Thumbprint);

    x509ProtectionParameters.InclusionMode = SecurityTokenInclusionMode.Never;


    messageSecurity.ProtectionTokenParameters = x509ProtectionParameters;

    HttpTransportBindingElement httpBinding = new HttpTransportBindingElement();


    binding = new CustomBinding(messageSecurity, httpBinding);


    return binding;         


Not as easy as I had hoped it would be, but it's working well now, so it's all good.  If you go the route of the custom token, it turns out there are all kinds of fun things you can do with token caching, etc.  It does require a fair amount of effort though, since there are 10-12 classes that you have to provide.

Tuesday, December 05, 2006 3:47:33 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# 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




                <behavior name="tokenBehavior">



                            <certificate findValue="CN=VoyagerClient" />

                            <authentication certificateValidationMode="PeerOrChainTrust"

                                revocationMode="NoCheck" />


                        <serviceCertificate findValue="CN=VoyagerServer" />

                        <issuedTokenAuthentication allowUntrustedRsaIssuers="true">


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

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









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


                        <message clientCredentialType="IssuedToken" />





the client side binding like so




                <behavior name="tokenBehavior">


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


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

                            <authentication certificateValidationMode="PeerOrChainTrust"

                                revocationMode="NoCheck" />








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


                     <message clientCredentialType="IssuedToken"/>





 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.


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


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


ClaimSet claimset = new DefaultClaimSet(claims);

cred.Claims = claimset;


CallBack callback = new CallBack();

InstanceContext ic = new InstanceContext(callback);

HelloWorldClient client = new HelloWorldClient(ic);



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);



CertificateValidationMode =



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




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



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


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]  | 
# Monday, November 06, 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, November 06, 2006 1:19:27 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, November 03, 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



        <binding name="UsernameBinding">

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






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



        <binding name="stsInfoCard">

          <security mode="Message">

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




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, November 03, 2006 3:27:57 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, November 01, 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, November 01, 2006 11:14:24 AM (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, November 01, 2006 11:13:15 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, October 17, 2006

After some minor setbacks, I’m finally getting going with ADAM, and amazed at how well it works (once you figure out how it’s supposed to work, which is a non-trivial undertaking).  One thing that makes it harder is that most of the (still scant) documentation around ADAM is geared toward IT Pros, not developers, so there are plenty of places where you track down the documentation for that critical change you need to make to your directory, only to be told “start the command line tool…”.  Frustrating, but workable. 

Once the magic incantations are prized forth, it seems very fast.  Granted we’re not doing anything tricky at this point, but adding users, setting passwords, simple queries, all seem pretty snappy. 

On my previous problems with ADAM and AzMan integration, this is apparently caused by the fact that I had my users in one application partition in ADAM, and my AzMan store in another partition in the same ADAM instance.  The official word is that this is not supported, which probably makes sense.  It means that I’ll probably end up using a separate ADAM instance as the AzMan store, or fall back to the XML file, although that’s harder to distribute.  Only time will tell.

Tuesday, October 17, 2006 10:32:08 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 

Over the weekend I took my kids for a hike up the Deschutes river from where it meets the Columbia, just east of the Dalles.  The weather was pretty nice, although it was overcast most of the day.  At least the rain held off until the middle of the night.  Check out pictures and a brief description at portlandhikers.com

This was the longest hike I’ve ever done with my kids, and as we’ve progressed toward longer hikes over the summer, I’ve learned some valuable lessons about hiking with children and how to make the trip more enjoyable for everyone.  I got a lot of great tips from Extreme Kids: How to Connect With Your Children Through Today's Extreme (and Not So Extreme) Outdoor Sports.  It’s a very well written book, that starts with some general tips about going outdoors with children, and then has some sport-specific information in the second half.  The tips I’ve gotten the most out of so far:

  • dress them for the part.  Hiking-specific gear like hydration packs, boots, and trekking poles make them feel like they are participating in something special, and really help get them out on the trail.
  • talk up the hike.  Take some time to talk up the hike.  Make it sound hard, question their ability to handle such a difficult task (not too seriously) and make it into a challenge.  This has made a huge difference.  My kids both boogied right up Little Belknap Crater after I played up the difficulty of “scaling a volcano”. 
  • keep them fed.  Keeping their blood sugar up is vital.  I’ve started packing not just granola/Clif bars, but some smaller snacks to keep them sugared up.  Generally we avoid giving them sugar, so this one took me a while to warm up to, but on last weekend’s 7.8 miler, it made a big difference.  They were tired, but the never crashed.  The new Jelly Belly “Sports Beans” work great for this.  They are basically jelly beans with electrolytes in them (like Gatorade) that come in 100 calorie packs.  The kids love them, and the feel like they are getting away with something. :-)  We also tried some Clif Shot Bloks, which proved popular.  They come in packs of 6, and were easy to dole out at key milestones.

These tips (and more from the book) have made our time together outside much more enjoyable.  I’m already looking forward to next season (and maybe some snowshoeing over the winter).

Tuesday, October 17, 2006 10:18:17 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |