<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Joe Kaplan</title>
    <link>http://www.joekaplan.net/</link>
    <description>.NET. LDAP. Geekery.</description>
    <language>en-us</language>
    <copyright>Joseph E. Kaplan</copyright>
    <lastBuildDate>Wed, 12 Mar 2008 04:41:56 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>blog@joekaplan.net</managingEditor>
    <webMaster>blog@joekaplan.net</webMaster>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=c59ba3ad-6e76-4aa0-9117-e52626283b4e</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,c59ba3ad-6e76-4aa0-9117-e52626283b4e.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,c59ba3ad-6e76-4aa0-9117-e52626283b4e.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=c59ba3ad-6e76-4aa0-9117-e52626283b4e</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It seems like I've deteriorated into semi-annual blog posts.  Sigh.  At
least the discussion groups at <a href="http://www.directoryprogramming.net">www.directoryprogramming.net</a> continue
to flourish and we are seeing a nice uptick in activity on the ADFS board there. 
I think the writing may be on the wall for me as a blogger, but who knows.  Perhaps
I'll get back on the wagon.
</p>
        <p>
Anyway, thanks to all the people who came to see my talks at DEC this year. 
I hope you enjoyed visiting my town and you got a lot out of the conference itself. 
DEC is one of my favorites and I'm happy to see it continue to do well.  I got
a lot of nice feedback on both of my talks and I'm always interested to hear what
you thought.
</p>
        <p>
My first talk this year was on customizing ADFS.  To my knowledge, this type
of stuff has never been talked about publicly before, so the session was a bit of
an experiment.  I essentially tried to cover all the different types of things
you should and could do to ADFS V1 or 1.1 (2003 R2 server or 2008 server) to make
it do different things.  It started off discussing some cosmetics to apply to
the pages displayed by the FS, moved through ADAM account store tweaks and then covered
custom claim transformation modules and some advanced hacks/mods such as non-Windows
authentication.  Some of that stuff has been discussed here on this blog and
nearly all of it was based on stuff we've actually done at work, so basically real
world experience.  My fear was that the subject matter would be a little over
the audience's head since it wasn't introductory at all (assumed you already knew
ADFS pretty well) and covered some developer stuff which might have seemed alien to
many of the audience members who tend to be more of the IT Pro sort.  Still,
I think it was valuable stuff.
</p>
        <p>
I mentioned a sample custom claim transform module that I'd post the source to. 
I'll follow that up in a separate post shortly.
</p>
        <p>
The audiences for all the ADFS talks were pretty small by comparison to the big AD
talks, but this doesn't surprise me.  Not only is ADFS still a new thing, but
to a great extent it is a luxury for most DEC attendees to be able to go to those
sessions.  ADFS largely assumes that both the directory and the identity provisioning
stuff is all a solved problem and that we have rich repositories filled with security
principals whose identity is trustworthy and stuffed with useful metadata that can
be converted to claims.  For many, that is not (yet) a solved problem at all
and federated identity is still largely wishful thinking.  Still, you have to
start somewhere.
</p>
        <p>
My second talk was essentially the talk I've done at DEC now for 3 years, although
this time modified heavily to cover the new .NET 3.5 stuff in System.DirectoryServices.AccountManagement. 
I was really dreading this talk and didn't finish the slides for it before the conference,
so between the last minute PPT work and the anxiety, I only got about an hour of sleep.
</p>
        <p>
Still, the talk seemed to go off pretty well.  I was in the big room this time
and in one of the last slots of the conference, so I had low expectations for turnout. 
It seemed like I had a pretty good crowd though (not the Dean and Joe show, but I'll
take it!) and people seemed to be into it.  I think it was probably the best
version of that talk I've done to date, so all in all I'm quite happy.  I miss
having <a href="http://www.dunnry.com/blog/">Ryan</a> there to bounce stuff around
with, but so it goes.
</p>
        <p>
Thanks also to <a href="http://blogs.msdn.com/donovanf/">Donovan</a> for inviting
me up for his case studies talk and giving me an opportunity to talk about some of
the real world stuff we are doing with federation at work and talking about the process
and legal stuff as much as the technical aspects.  People clearly have as many
if not more questions about those things than the engineering parts.
</p>
        <p>
I think I finally get CardSpace now, especially as it applies to the enterprise, and
am looking forward to having a chance to get it running internally.  That should
be interesting.  Stuart, I need some bits I can actually deploy.  :) 
Thanks to <a href="http://pamelaproject.com/">Pamela Dingle</a> for coming to DEC
and bringing both the CardSpace love and the non-MS platform perspective.  I'm
anxious to go to a conference where everyone knows her and no one knows me at all
and see how I do.
</p>
        <p>
She's got a nice <a href="http://eternaloptimist.wordpress.com/2008/03/10/dec-2008-this-ones-for-you-wook/">follow
up</a> on the Wook Lee Challenge this year which I played a tiny role in.
</p>
        <p>
        </p>
        <p>
          <a href="http://www.joekaplan.net/content/binary/Customizing-ADFS.zip">Customizing-ADFS.zip
(1.06 MB)</a>
        </p>
        <p>
          <a href="http://www.joekaplan.net/content/binary/DotNet-DS-Programming.zip">DotNet-DS-Programming.zip
(1.27 MB)</a>
        </p>
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=c59ba3ad-6e76-4aa0-9117-e52626283b4e" />
      </body>
      <title>DEC 2008 Wrap Up and Materials</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,c59ba3ad-6e76-4aa0-9117-e52626283b4e.aspx</guid>
      <link>http://www.joekaplan.net/DEC2008WrapUpAndMaterials.aspx</link>
      <pubDate>Wed, 12 Mar 2008 04:41:56 GMT</pubDate>
      <description>&lt;p&gt;
It seems like I've deteriorated into semi-annual blog posts.&amp;nbsp; Sigh.&amp;nbsp; At
least the discussion groups at &lt;a href="http://www.directoryprogramming.net"&gt;www.directoryprogramming.net&lt;/a&gt; continue
to flourish and we are seeing a nice uptick in activity on the ADFS board there.&amp;nbsp;
I think the writing may be on the wall for me as a blogger, but who knows.&amp;nbsp; Perhaps
I'll get back on the wagon.
&lt;/p&gt;
&lt;p&gt;
Anyway, thanks to all the people who came to see my talks at DEC this year.&amp;nbsp;
I hope you enjoyed visiting my town and you got a lot out of the conference itself.&amp;nbsp;
DEC is one of my favorites and I'm happy to see it continue to do well.&amp;nbsp; I got
a lot of nice feedback on both of my talks and I'm always interested to hear what
you thought.
&lt;/p&gt;
&lt;p&gt;
My first talk this year was on customizing ADFS.&amp;nbsp; To my knowledge, this type
of stuff has never been talked about publicly before, so the session was a bit of
an experiment.&amp;nbsp; I essentially tried to cover all the different types of things
you should and could do to ADFS V1 or 1.1 (2003 R2 server or 2008 server) to make
it do different things.&amp;nbsp; It started off discussing some cosmetics to apply to
the pages displayed by the FS, moved through ADAM account store tweaks and then covered
custom claim transformation modules and some advanced hacks/mods such as non-Windows
authentication.&amp;nbsp; Some of that stuff has been discussed here on this blog and
nearly all of it was based on stuff we've actually done at work, so basically real
world experience.&amp;nbsp; My fear was that the subject matter would be a little over
the audience's head since it wasn't introductory at all (assumed you already knew
ADFS pretty well) and covered some developer stuff which might have seemed alien to
many of the audience members who tend to be more of the IT Pro sort.&amp;nbsp; Still,
I think it was valuable stuff.
&lt;/p&gt;
&lt;p&gt;
I mentioned a sample custom claim transform module that I'd post the source to.&amp;nbsp;
I'll follow that up in a separate post shortly.
&lt;/p&gt;
&lt;p&gt;
The audiences for all the ADFS talks were pretty small by comparison to the big AD
talks, but this doesn't surprise me.&amp;nbsp; Not only is ADFS still a new thing, but
to a great extent it is a luxury for most DEC attendees to be able to go to those
sessions.&amp;nbsp; ADFS largely assumes that both the directory and the identity provisioning
stuff is all a solved problem and that we have rich repositories filled with security
principals whose identity is trustworthy and stuffed with useful metadata that can
be converted to claims.&amp;nbsp; For many, that is not (yet) a solved problem at all
and federated identity is still largely wishful thinking.&amp;nbsp; Still, you have to
start somewhere.
&lt;/p&gt;
&lt;p&gt;
My second talk was essentially the talk I've done at DEC now for 3 years, although
this time modified heavily to cover the new .NET 3.5 stuff in System.DirectoryServices.AccountManagement.&amp;nbsp;
I was really dreading this talk and didn't finish the slides for it before the conference,
so between the last minute PPT work and the anxiety, I only got about an hour of sleep.
&lt;/p&gt;
&lt;p&gt;
Still, the talk seemed to go off pretty well.&amp;nbsp; I was in the big room this time
and in one of the last slots of the conference, so I had low expectations for turnout.&amp;nbsp;
It seemed like I had a pretty good crowd though (not the Dean and Joe show, but I'll
take it!) and people seemed to be into it.&amp;nbsp; I think it was probably the best
version of that talk I've done to date, so all in all I'm quite happy.&amp;nbsp; I miss
having &lt;a href="http://www.dunnry.com/blog/"&gt;Ryan&lt;/a&gt; there to bounce stuff around
with, but so it goes.
&lt;/p&gt;
&lt;p&gt;
Thanks also to &lt;a href="http://blogs.msdn.com/donovanf/"&gt;Donovan&lt;/a&gt; for inviting
me up for his case studies talk and giving me an opportunity to talk about some of
the real world stuff we are doing with federation at work and talking about the process
and legal stuff as much as the technical aspects.&amp;nbsp; People clearly have as many
if not more questions about those things than the engineering parts.
&lt;/p&gt;
&lt;p&gt;
I think I finally get CardSpace now, especially as it applies to the enterprise, and
am looking forward to having a chance to get it running internally.&amp;nbsp; That should
be interesting.&amp;nbsp; Stuart, I need some bits I can actually deploy.&amp;nbsp; :)&amp;nbsp;
Thanks to &lt;a href="http://pamelaproject.com/"&gt;Pamela Dingle&lt;/a&gt; for coming to DEC
and bringing both the CardSpace love and the non-MS platform perspective.&amp;nbsp; I'm
anxious to go to a conference where everyone knows her and no one knows me at all
and see how I do.
&lt;/p&gt;
&lt;p&gt;
She's got a nice &lt;a href="http://eternaloptimist.wordpress.com/2008/03/10/dec-2008-this-ones-for-you-wook/"&gt;follow
up&lt;/a&gt; on the Wook Lee Challenge this year which I played a tiny role in.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.joekaplan.net/content/binary/Customizing-ADFS.zip"&gt;Customizing-ADFS.zip
(1.06 MB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.joekaplan.net/content/binary/DotNet-DS-Programming.zip"&gt;DotNet-DS-Programming.zip
(1.27 MB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=c59ba3ad-6e76-4aa0-9117-e52626283b4e" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,c59ba3ad-6e76-4aa0-9117-e52626283b4e.aspx</comments>
      <category>General;Identity Federation;LDAP</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=86b985f5-ff32-4efc-b477-d72517dc98f3</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,86b985f5-ff32-4efc-b477-d72517dc98f3.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,86b985f5-ff32-4efc-b477-d72517dc98f3.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=86b985f5-ff32-4efc-b477-d72517dc98f3</wfw:commentRss>
      <slash:comments>7</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Given that I haven't posted on this blog for months, I'm not sure if anyone still
reads it, but I thought I'd take a few moments to inform my loyal readers of a new
addition to the family.
</p>
        <p>
Micah Kaplan Yarbrough was born October 15, 2007 at 11:40 AM at Prentise Women's Hospital
(part of Northwestern Memorial Hospital) in downtown Chicago, just like like his older
brother Evan.
</p>
        <p>
He arrived 10 days before he was expected and almost a month sooner than his brother
(who was quite late) and was a little smaller, but still a robust 7lb 11oz and 20.25"
long.
</p>
        <p>
Mom and baby are doing fine.  They are both sleeping right now in fact. 
We'll be heading home in a few days and start to figure out the mysteries of chasing
two kids around.
</p>
        <p>
Evan is at home with his grandparents right now trying to convince them that he goes
to bed at 10:30 usually and get 10 cookies everynight before bed.
</p>
        <p>
Here is a picture at 1 hour old.  He was sleeping then too.  He sleeps a
lot so far.  He barely ever cries, but I'm sure he's just building up his strength
for later. :)
</p>
        <img src="http://www.joekaplan.net/content/binary/babymicahsmall.jpg" border="0" />
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=86b985f5-ff32-4efc-b477-d72517dc98f3" />
      </body>
      <title>Welcome to the world, baby Micah!</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,86b985f5-ff32-4efc-b477-d72517dc98f3.aspx</guid>
      <link>http://www.joekaplan.net/WelcomeToTheWorldBabyMicah.aspx</link>
      <pubDate>Tue, 16 Oct 2007 14:23:54 GMT</pubDate>
      <description>&lt;p&gt;
Given that I haven't posted on this blog for months, I'm not sure if anyone still
reads it, but I thought I'd take a few moments to inform my loyal readers of a new
addition to the family.
&lt;/p&gt;
&lt;p&gt;
Micah Kaplan Yarbrough was born October 15, 2007 at 11:40 AM at Prentise Women's Hospital
(part of Northwestern Memorial Hospital) in downtown Chicago, just like like his older
brother Evan.
&lt;/p&gt;
&lt;p&gt;
He arrived 10 days before he was expected and almost a month sooner than his brother
(who was quite late) and was a little smaller, but still a robust 7lb 11oz and 20.25"
long.
&lt;/p&gt;
&lt;p&gt;
Mom and baby are doing fine.&amp;nbsp; They are both sleeping right now in fact.&amp;nbsp;
We'll be heading home in a few days and start to figure out the mysteries of chasing
two kids around.
&lt;/p&gt;
&lt;p&gt;
Evan is at home with his grandparents right now trying to convince them that he goes
to bed at 10:30 usually and get 10 cookies everynight before bed.
&lt;/p&gt;
&lt;p&gt;
Here is a picture at 1 hour old.&amp;nbsp; He was sleeping then too.&amp;nbsp; He sleeps a
lot so far.&amp;nbsp; He barely ever cries, but I'm sure he's just building up his strength
for later. :)
&lt;/p&gt;
&lt;img src="http://www.joekaplan.net/content/binary/babymicahsmall.jpg" border=0&gt;&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=86b985f5-ff32-4efc-b477-d72517dc98f3" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,86b985f5-ff32-4efc-b477-d72517dc98f3.aspx</comments>
      <category>General</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=5c846938-9aba-467a-b1b0-99bbef193bcb</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,5c846938-9aba-467a-b1b0-99bbef193bcb.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,5c846938-9aba-467a-b1b0-99bbef193bcb.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=5c846938-9aba-467a-b1b0-99bbef193bcb</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was lucky enough to attend DEC again this year and was even more lucky to have been
asked to speak due to an unfortunate last minute cancellation.  This year, I
presented on a variation of the same type of stuff that Ryan and I <a href="http://dunnry.com/blog/DEC2006WrapUpAndPresentationMaterial.aspx">presented
on at DEC 2006</a>.  This year, I had to fly solo as Ryan could not attend. 
:(
</p>
        <p>
Here's what we did differently this time around:
</p>
        <ul>
          <li>
No PowerShell (DEC already had 2 PowerShell sessions, so why bother?) 
</li>
          <li>
Focus on some new Longhorn LDAP and AD features (Fine Grained Password Policy) 
</li>
          <li>
A "slideware" overview of what's coming in .NET 3.5 "Orcas" with the new System.DirectoryServices.AccountManagement
namespace (formerly known as the Principal API).</li>
        </ul>
        <p>
I'd like to thank all of those who attended.  I hope you enjoyed the talk and
hope that some of you got free books.  I apologize if I could not accomodate
all of you.  :(  Thanks to the <a href="http://www.awprofessional.com/index.asp?rl=1">Addison-Wesley</a> marketing
team for providing the books for your enjoyment.
</p>
        <p>
For those of you interested in the Snippet Compiler tool I used in my demos, you can
find it <a href="http://www.sliver.com/dotnet/SnippetCompiler/">here</a>.
</p>
        <p>
The slides and code for the demos are attached and I did get around to converting
them to VB for all of you VB people (I'm a VB.NET guy too; I really don't know why
I coded all the demos in C# :)).  
</p>
        <p>
Note that my application of the "in chain" matching rule turns out to be incorrect
usage.  Don't do it like that!  Read more <a href="http://www.joekaplan.net/InChainMatchingRuleShouldNotBeUsedForTransitiveLinkExpansion.aspx">here</a>. 
I feel silly.
</p>
        <p>
Note that if you are confused about which API to use, S.DS or S.DS.P, I discussed
that in some detail <a href="http://www.joekaplan.net/ATaleOfTwoLDAPStacks.aspx">here</a>. 
There is really no right answer, but hopefully that helps.  
</p>
        <p>
To ask us any specific questions about LDAP programming, please use the book's <a href="http://www.directoryprogramming.net">discussion
forum</a>.  This is the only place that Ryan and I both use together.
</p>
        <p>
As always, DEC is a treat and I really enjoyed all the conversations and interaction
and am happy to see ADFS gaining a little traction.  Now, about that hot chicken...
</p>
        <a href="http://www.joekaplan.net/content/binary/DEC2007.zip">DEC2007.zip (536.52
KB)</a>
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=5c846938-9aba-467a-b1b0-99bbef193bcb" />
      </body>
      <title>DEC 2007 Follow Up</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,5c846938-9aba-467a-b1b0-99bbef193bcb.aspx</guid>
      <link>http://www.joekaplan.net/DEC2007FollowUp.aspx</link>
      <pubDate>Fri, 27 Apr 2007 16:58:34 GMT</pubDate>
      <description>&lt;p&gt;
I was lucky enough to attend DEC again this year and was even more lucky to have been
asked to speak due to an unfortunate last minute cancellation.&amp;nbsp; This year, I
presented on a variation of the same type of stuff that Ryan and I &lt;a href="http://dunnry.com/blog/DEC2006WrapUpAndPresentationMaterial.aspx"&gt;presented
on at DEC 2006&lt;/a&gt;.&amp;nbsp; This year, I had to fly solo as Ryan could not attend.&amp;nbsp;
:(
&lt;/p&gt;
&lt;p&gt;
Here's what we did differently this time around:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
No PowerShell (DEC already had 2 PowerShell sessions, so why bother?) 
&lt;li&gt;
Focus on some new Longhorn LDAP and AD features (Fine Grained Password Policy) 
&lt;li&gt;
A "slideware" overview of what's coming in .NET 3.5 "Orcas" with the new System.DirectoryServices.AccountManagement
namespace (formerly known as the Principal API).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I'd like to thank all of those who attended.&amp;nbsp; I hope you enjoyed the talk and
hope that some of you got free books.&amp;nbsp; I apologize if I could not accomodate
all of you.&amp;nbsp; :(&amp;nbsp; Thanks to the &lt;a href="http://www.awprofessional.com/index.asp?rl=1"&gt;Addison-Wesley&lt;/a&gt; marketing
team for providing the books for your enjoyment.
&lt;/p&gt;
&lt;p&gt;
For those of you interested in the Snippet Compiler tool I used in my demos, you can
find it &lt;a href="http://www.sliver.com/dotnet/SnippetCompiler/"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The slides and code for the demos are attached and I did get around to converting
them to VB for all of you VB people (I'm a VB.NET guy too; I really don't know why
I coded all the demos in C# :)).&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Note that my application of the "in chain" matching rule turns out to be incorrect
usage.&amp;nbsp; Don't do it like that!&amp;nbsp; Read more &lt;a href="http://www.joekaplan.net/InChainMatchingRuleShouldNotBeUsedForTransitiveLinkExpansion.aspx"&gt;here&lt;/a&gt;.&amp;nbsp;
I feel silly.
&lt;/p&gt;
&lt;p&gt;
Note that if you are confused about which API to use, S.DS or S.DS.P, I discussed
that in some detail &lt;a href="http://www.joekaplan.net/ATaleOfTwoLDAPStacks.aspx"&gt;here&lt;/a&gt;.&amp;nbsp;
There is really no right answer, but hopefully that helps.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
To ask us any specific questions about LDAP programming, please use the book's &lt;a href="http://www.directoryprogramming.net"&gt;discussion
forum&lt;/a&gt;.&amp;nbsp; This is the only place that Ryan and I both use together.
&lt;/p&gt;
&lt;p&gt;
As always, DEC is a treat and I really enjoyed all the conversations and interaction
and am happy to see ADFS gaining a little traction.&amp;nbsp; Now, about that hot chicken...
&lt;/p&gt;
&lt;a href="http://www.joekaplan.net/content/binary/DEC2007.zip"&gt;DEC2007.zip (536.52
KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=5c846938-9aba-467a-b1b0-99bbef193bcb" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,5c846938-9aba-467a-b1b0-99bbef193bcb.aspx</comments>
      <category>General;Identity Federation;LDAP</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=622e9be0-6539-4ddc-8096-820c33893ffc</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,622e9be0-6539-4ddc-8096-820c33893ffc.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,622e9be0-6539-4ddc-8096-820c33893ffc.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=622e9be0-6539-4ddc-8096-820c33893ffc</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft has added a new LDAP feature to AD in Windows 2003 SP2 and Longhorn server
called the LDAP_MATCHING_RULE_IN_CHAIN.  Essentially, it is an extension filter
type that allows you to search withing the content of a distinguished name-syntax
attribute and do matching throughout the entire chain of linked values instead of
just within the immediate values.  The docs are <a href="http://msdn2.microsoft.com/en-us/library/aa746475.aspx">here</a> and
the syntax looks like this:
</p>
        <p>
          <font face="Courier New">(memberOf:1.2.840.113556.1.4.1941:=CN=some group,CN=xxxx,DC=xxxx,DC=xxxx)</font>
        </p>
        <p>
I showed some examples of this in my talk at DEC where I used some searches with and
without the extension filter type to show traversal of some nested group membership.
</p>
        <p>
          <a href="http://dunnry.com/blog/">Ryan</a> also <a href="http://dunnry.com/blog/TransitiveLinkValueFilterEvaluation.aspx">wrote
about this</a> a while ago and discovered that while useful, this technique is very
slow for expanding group membership and it seems to be much faster to just use recursive
searches.
</p>
        <p>
As it turns out, the problem is that we were trying to use this feature incorrectly. 
The "In Chain" filter type should NOT be used for transitive link expansion! 
It is intended to be used for matching only.  Perhaps that's why they called
it LDAP_MATCHING_RULE_IN_CHAIN.  :)
</p>
        <p>
As such, you should really only use it in a base level query.  If you use the
filter shown above in a base level query, it will still tell you if the object that
is used as the search root is a member of the specified group anywhere in the nesting
chain, but it will perform fine.  If you use it for anything else, you are asking
for trouble.  
</p>
        <p>
Now, when will we get some sort of transitive link expansion widget that actually
works well for this purpose?
</p>
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=622e9be0-6539-4ddc-8096-820c33893ffc" />
      </body>
      <title>In Chain Matching Rule should not be Used for Transitive Link Expansion</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,622e9be0-6539-4ddc-8096-820c33893ffc.aspx</guid>
      <link>http://www.joekaplan.net/InChainMatchingRuleShouldNotBeUsedForTransitiveLinkExpansion.aspx</link>
      <pubDate>Fri, 27 Apr 2007 15:24:21 GMT</pubDate>
      <description>&lt;p&gt;
Microsoft has added a new LDAP feature to AD in Windows 2003 SP2 and Longhorn server
called the LDAP_MATCHING_RULE_IN_CHAIN.&amp;nbsp; Essentially, it is an extension filter
type that allows you to search withing the content of a distinguished name-syntax
attribute and do matching throughout the entire chain of linked values instead of
just within the immediate values.&amp;nbsp; The docs are &lt;a href="http://msdn2.microsoft.com/en-us/library/aa746475.aspx"&gt;here&lt;/a&gt; and
the syntax looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;(memberOf:1.2.840.113556.1.4.1941:=CN=some group,CN=xxxx,DC=xxxx,DC=xxxx)&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
I showed some examples of this in my talk at DEC where I used some searches with and
without the extension filter type to show traversal of some nested group membership.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://dunnry.com/blog/"&gt;Ryan&lt;/a&gt; also &lt;a href="http://dunnry.com/blog/TransitiveLinkValueFilterEvaluation.aspx"&gt;wrote
about this&lt;/a&gt; a while ago and discovered that while useful, this technique is very
slow for expanding group membership and it seems to be much faster to just use recursive
searches.
&lt;/p&gt;
&lt;p&gt;
As it turns out, the problem is that we were trying to use this feature incorrectly.&amp;nbsp;
The "In Chain" filter type should NOT be used for transitive link expansion!&amp;nbsp;
It is intended to&amp;nbsp;be used for matching only.&amp;nbsp; Perhaps that's why they called
it LDAP_MATCHING_RULE_IN_CHAIN.&amp;nbsp; :)
&lt;/p&gt;
&lt;p&gt;
As such, you should really only use it in a base level query.&amp;nbsp; If you use the
filter shown above in a base level query, it will still tell you if the object that
is used as the search root is a member of the specified group anywhere in the nesting
chain, but it will perform fine.&amp;nbsp; If you use it for anything else, you are asking
for trouble.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Now, when will we get some sort of transitive link expansion widget that actually
works well for this purpose?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=622e9be0-6539-4ddc-8096-820c33893ffc" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,622e9be0-6539-4ddc-8096-820c33893ffc.aspx</comments>
      <category>LDAP</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=d41ff2af-fa75-4252-8f93-37c88b019dbe</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,d41ff2af-fa75-4252-8f93-37c88b019dbe.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,d41ff2af-fa75-4252-8f93-37c88b019dbe.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=d41ff2af-fa75-4252-8f93-37c88b019dbe</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been using ADFS day in and day out for almost a year now and have run into a
fairly stunning number of issues.  Most of these are simple problems with simple
solutions, but they can cause hours or days of frustration to resolve.  One of
the main themes that seems to pervade these little doses of IT misery is based on
a misunderstanding of how cookies work and how ADFS uses cookies.  This post
is my attempt to gather some of the lessons I've learned and hopefully make your time
with ADFS a little easier.  
</p>
        <p>
          <font size="5">How Cookies Work in Web Browsers</font>
        </p>
        <p>
Although many of us have a basic, foggy notion about what cookies do in web applications,
many of us don't know all of the little rules that govern their behavior.  I'll
try to run that down now based on my own understanding, which I believe is at least
technically accurate enough for the purposes of the rest of this article.  Feel
free to correct me if you know better or refer to the RFCs if you want more precision.
</p>
        <p>
Basically, a cookie is a small piece of textual data that is sent by a web server
to a web browser.  The job of the browser is to return this piece of data back
to the server when it makes another request to the server, based on the rules that
I'll detail shortly.  Cookies are generally used in web applications as a means
of maintaining state in the web server across multiple requests made by the browser.
</p>
        <p>
Cookies are implemented as well-known HTTP headers in the request data sent by the
browser and the response data sent.  The request header name is called <font face="Courier New"><strong>Cookie</strong></font> and
the response header name is <strong><font face="Courier New">Set-Cookie</font></strong>. 
The server always initiates the usage of cookies by returning a response with a <font face="Courier New"><strong>Set-Cookie</strong></font> header
in it that contains the data and some other instructions.  The browser's job
is to then add a <font face="Courier New"><strong>Cookie</strong></font> header on
all subsequent requests to the server that contains exactly the data the server sent
in the <strong><font face="Courier New">Set-Cookie</font></strong> header.  However,
exactly when the browser will add the <font face="Courier New"><strong>Cookie</strong></font> header
to its request is based on the other instructions in the <font face="Courier New"><strong>Set-Cookie</strong></font> header
and the rules for cookie behavior.  
</p>
        <p>
First, let's examine the "other instructions".  The <strong><font face="Courier New">Set-Cookie</font></strong> header
may contain these bits of info:
</p>
        <ul>
          <li>
Name 
</li>
          <li>
Value 
</li>
          <li>
Domain (optional) 
</li>
          <li>
Path (optional) 
</li>
          <li>
Expires (optional) 
</li>
          <li>
Secure flag (optional) 
</li>
          <li>
HttpOnly flag (optional)</li>
        </ul>
        <p>
          <font size="4">Cookie Name and Value</font>
        </p>
        <p>
The Cookie Name is just what it sounds like.  Since a web app may use many different
cookies, this is how they can be distinguished.  The Cookie Value is just some
textual data.  It could be anything.  Oftentimes, it may contain some data
that has been encrypted that the browser can't even interpret it--only the server
can.  This is not a problem.  The data is for the server anyway.  The
browser's job is to dutifully sending it back to the server, not understand it.
</p>
        <p>
          <font size="4">Cookie Expires, Secure and HttpOnly</font>
        </p>
        <p>
I'll skip ahead to the last three, as they easy to explain and not terribly problematic
(for our purposes).  The optional Expires field may contain a
date/time value that tells the browser when to stop sending the cookie back to the
server.  This one is interesting because it alone determines whether a cookie
is a <strong>session cookie</strong> or a <strong>file-based cookie</strong>.  
</p>
        <p>
If there is no expiration specified, the cookie defaults to a session cookie and will
be returned as long as the browser session continues.  In IE and FireFox (and
probably most other browsers on Windows), the session is basically the duration that
the browser <em>process</em> is open.  Note that a browser process may span many
windows and may originate in a non-obvious place like an email or an instant messenger
client, so you may sometimes be surprised to see a cookie being sent back to a server
even after a window was closed (or seemingly all windows for that matter!).  
</p>
        <p>
If the expiration date is set, then the cookie is "file-based" and will be written
to disk.  It will survive across multiple browser processes being launched and
stopped.  The browser will continue to send it until the expiration time is exceeded.
</p>
        <p>
The Secure flag instructs the browser to only return the cookie back to the server
if the request uses the HTTPS (SSL) protocol.  This flag is often used when the
cookie contains sensitive data that could be useful by a bad guy if it was intercepted
on the wire.  I consider it to be bad practice to ever use any kind of forms-based
authentication cookie without the Secure flag set, although this then requires SSL. 
If you are serious about security, you use SSL for secure websites.  End of story.
</p>
        <p>
The HttpOnly flag is the new guy and not all browsers support it (although many do). 
It basically says that this cookie will only be sent on the wire.  The browser
will not allow the cookie to show up in the browser's Document Object Model (DOM)
cookie collection.  This prevents scripts from being able to view and manipulate
the cookie and can help prevent some kinds of cross-site scripting (XSS) attacks.
</p>
        <p>
          <font size="4">Cookie Domain</font>
        </p>
        <p>
For our purposes, The Cookie Domain and Path are the most interesting values, as this
is the heart of all of the trouble in ADFS, so we cover them last.  The domain
specifies which hosts the browser will replay the cookie to.  If the domain is
not specified, the browser will only replay the cookie to host that sent the <font face="Courier New"><strong>Set-Cookie</strong></font> header
in the first place.  Here, the host is determined by the host portion of the
URL.  For example, in <a href="http://www.joekaplan.net/default.aspx">http://www.joekaplan.net/default.aspx</a>,
the host is <font face="Courier New" color="#0000ff">www.joekaplan.net</font>.  
</p>
        <p>
Domains can also be specified hierarchically.  I could set the cookie domain
to <font face="Courier New" color="#0000ff">.joekaplan.net</font> and then my browser
would return the cookie to any host within the <font face="Courier New" color="#0000ff">joekaplan.net</font> DNS
namespace such as <font face="Courier New" color="#0000ff">www.joekaplan.net</font>, <font face="Courier New" color="#0000ff">blogs.joekaplan.net</font> and <font face="Courier New" color="#0000ff">junk.joekaplan.net</font> (neither
of which exist in the latter two examples, but that isn't important).
</p>
        <p>
One might wonder if one can set a cookie for a domain other than the domain of the
host.  The answer is "it depends", but usually no.  As one can imagine,
this could (and has!) lead to all kinds of crazy hacking where one site writes over
another site's cookies.  In IE, the ability to do this is locked down by the
various security levels and assigned by zone.  I haven't seen many legitimate
uses for such a design personally, so I'm happy this is restricted now.
</p>
        <p>
Another important picky detail about the domain value is that it doesn't consider
the port component of the hostname in the URL.  Basically, this means that it
treats the host <font face="Courier New" color="#0000ff">www.joekaplan.net:80</font> and <font face="Courier New" color="#0000ff">www.joekaplan.net:8080</font> as <strong><em>the
same host</em></strong>, even if those map to completely different websites on your
web server.  This can lead to surprises.
</p>
        <p>
          <font size="4">Cookie Path</font>
        </p>
        <p>
The final modifier is the Path.  The path value is like the domain, except that
is specifies the scope in the path hierarchy that the cookie will be replayed to. 
Here, the path is the part of the URL that comes after the host name.  If the
path is set to <font face="Courier New" color="#0000ff">/</font>, then the cookie
will be replayed to any part of the hierarchy of the website.  If the path is
set to <font face="Courier New" color="#0000ff">/site</font>, then the cookie will
only be replayed to requests for URLs at or below <font face="Courier New" color="#0000ff">/site</font>.
</p>
        <p>
One tricky detail with the path value is that it is <strong><em>case-sensitive</em></strong>. 
If you set the path to <font face="Courier New" color="#0000ff">/site</font> and your
URL is <font face="Courier New" color="#0000ff">http://www.joekaplan.net/Site/default.aspx</font> (note
the capital "S"), guess what?  The cookie will not be returned with the request! 
This little gotcha can easily confound IIS developers, as IIS is generally quite happy
to treat folders and virtual directories as case-insensitive.  Developers on
"other" web server platforms where URLs (and file names) are case-sensitive tend to
be a little more hip to this. :)
</p>
        <p>
          <font size="5">A Brief Tour of the ADFS Cookies</font>
        </p>
        <p>
ADFS, like most other HTTP authentication protocols that don't use the built in HTTP
authentication specifications (Basic, Digest, Negotiate, Kerberos, NTLM, etc.), use
cookies for a lot of stuff.  There are three primary cookies to know about:
</p>
        <ul>
          <li>
Authentication/Token cookie (<font face="Courier New" color="#0000ff">_WebSsoAuth</font>) 
</li>
          <li>
Home Realm Cookie (<font face="Courier New" color="#0000ff">_LSRealm</font>) 
</li>
          <li>
Logout Cookie (<font face="Courier New" color="#0000ff">_LSCleanup</font>)</li>
        </ul>
        <p>
Let's take each in turn.
</p>
        <p>
          <font size="4">Authentication/Token Cookie</font>
        </p>
        <p>
The <font face="Courier New" color="#0000ff">_WebSsoAuth</font> cookie is certainly
the most important one, as that is the cookie that represents the user's login to
a federation resource.  This cookie is always a session cookie, in that the Expires
field is never set, so it goes away when the browser process does.  Expiration
of this cookie is handled by timestamps set in the data in the cookie itself and is
a programmatic feature of the protocol and is not related to how the browser treats
cookie expiration.  
</p>
        <p>
The cookie basically contains the SAML 1.1 token issued by a federation server that
allows access to a specific resource.  The format of the cookie for ADFS is in
some crazy compressed format that MS came up with that isn't documented, but that
is supposedly cool because the WS-Federation PRP spec doesn't actually contain any
details about what this should look like and leaves it implementation specific. 
These cookies are only consumed by the server/app that issued them (hopefully!), so
this isn't a big deal.  Sometimes you may see a <font face="Courier New" color="#0000ff">_WebSsoAuth0</font> cookie
or additional numbering.  This can happen if the SAML token is very large and
the compressed size of the XML in the SAML token may exceed the allowed size of a
cookie.  ADFS breaks these up for you to overcome this.  This is a picky
and unimportant detail for our discussion, but I figured I'd mention it in case you
saw it and were curious.
</p>
        <p>
The <font face="Courier New"><strong>Set-Cookie</strong></font> header for this cookie
usually looks something like this (data clipped for brevity):
</p>
        <p>
          <font face="Courier New" color="#0000ff">Set-Cookie: _WebSsoAuth=eNrNWWuTqkgS9acYzpfd6LV5qAhGd8cWDxUVFMVnbMREASWiQ.....CdagA;
path=/adfs/ls/; secure; HttpOnly</font>
        </p>
        <p>
In this case, this is the authentication cookie issued by the federation server itself. 
In ADFS, each federation server the user logs in to (at least one, maybe two if there
is an account partner/resource partner set up) will issue a <font face="Courier New" color="#0000ff">_WebSsoAuth</font> cookie. 
Additionally, each application that the user visits will issue a <font face="Courier New" color="#0000ff">_WebSsoAuth</font> cookie
that is specific to the application.  
</p>
        <p>
Each <font face="Courier New" color="#0000ff">_WebSsoAuth</font> cookie is <em>different</em> and <em>is
intended only for the app/server that issued it</em>.  However, you probably
noticed how they all have the same name.  Because they all have the same
name, they must different by <em>domain</em> and <em>path</em> so that the browser
will know which cookie to send to which app/server.  If you've ever configured
an ADFS token-based or claims-based application, you will have noticed that you are
required to specify the domain and path for the cookie when configuring the application. 
All it takes is a naive mistake with this configuration to cause the browser to start
sending the wrong cookie to the wrong place and ADFS chaos ensues.
</p>
        <p>
          <font size="4">Home Realm Cookie</font>
        </p>
        <p>
The <font face="Courier New" color="#0000ff">_LSRealm</font> cookie is a file-based
cookie issued by the resource federation server after you have successfully logged
in that specifies the federation server URI (usually <font face="Courier New">urn:federation:foo</font> or
something) of the server that authenticated you.  This is done so that the resource
federation server doesn't have to prompt you for your home organization again if it
has multiple potential partners.  We already discussed a little bit about these
values and home realm discovery query strings in a <a href="http://www.joekaplan.net/NoteToUrnfederationself.aspx">post</a> last
summer, so I won't get into much more detail.  These things rarely cause trouble
except that you have to clear your cookies if you want to get a resource federation
server to prompt you for your home realm again after you log in the first time. 
They are issued for one month as I recall; I'm too lazy to check for certain right
now.  :)
</p>
        <p>
          <font size="4">Logout Cookie</font>
        </p>
        <p>
The <font face="Courier New" color="#0000ff">_LSCleanup</font> cookie assists in the
logout process by keeping track of which federation servers and applications you've
visited.  When ADFS does a log out, it attempts to "drain the swamp" by logging
you out of <strong>everything</strong>.  To do this, the built-in logout page
attempts to visit the logout URL for every federation server you've visited and every
app you've visited.  These logout URLs set the <font face="Courier New" color="#0000ff">_WebSsoAuth</font> cookie
value for the cookies they issued to "null".  This cookie is also a session cookie. 
These cookies can get screwed up just like the authentication cookies, but usually
this fact never comes up because once the authentication cookies are hosed, things
tend to break before you ever try to log out.
</p>
        <p>
          <font size="5">Common ADFS Problems Caused by Incorrect Cookie Settings</font>
        </p>
        <p>
There are two ADFS problems I've seen frequently that cause much pain that are related
to cookie problems and probably some variants that I'm forgetting:
</p>
        <ul>
          <li>
Invalid SAML Audience 
</li>
          <li>
Infinite Loop Detected</li>
        </ul>
        <p>
          <font size="4">Invalid SAML Audience</font>
        </p>
        <p>
This occurs when one ADFS application get's another ADFS application's cookie. 
Like I said before, each application has an application-specific cookie and there
is a piece of data in the SAML token called the <em>audience</em> that says exactly
where the cookie was supposed to go.  This is identified by the application's
configured URL in the trust policy and the web site.  
</p>
        <p>
There are a variety of ways you can create this error.  One easy way is by setting
the cookie domain to something like <font face="Courier New" color="#0000ff">.domain.com</font> and
having your apps set up with host names like <font face="Courier New" color="#0000ff">app1.domain.com</font> and <font face="Courier New" color="#0000ff">app2.domain.com</font>. 
Since these are both basically children of <font face="Courier New" color="#0000ff">.domain.com</font>,
the browser will happily send a <font face="Courier New" color="#0000ff">_WebSsoAuth</font> cookie
to <strong>app2</strong> that <strong>app1</strong> issued if the paths are the same. 
Since the path is often set to <font face="Courier New" color="#0000ff">/</font>,
this is not uncommon.  You can also have pseudo-chaos that is even more difficult
to debug if the path's aren't the same but contain some overlap in hierarchy.
</p>
        <p>
I'm still trying to figure out a reason why you would ever set the cookie domain in
an ADFS system.  Generally, you only ever want an ADFS cookie going back to the
host that issued it, so why not leave it at the default setting of "null"?  In
my experience, nothing but trouble ever comes from setting the domain.  If you
think of a use case for setting this, please let me know.
</p>
        <p>
I also mentioned overlapping paths.  These are a significant cause of trouble. 
Let's say you have an app at the root of the site <font face="Courier New" color="#0000ff">/</font> and
an app below that <font face="Courier New" color="#0000ff">/Site</font>.  Basically,
if they have the same host name, <em>you can't do that in ADFS</em>.  They need
to be strict siblings like <font face="Courier New" color="#0000ff">/Site1</font> and <font face="Courier New" color="#0000ff">/Site2</font>.  
</p>
        <p>
Overlapping paths can show up in subtle ways as well.  Sometimes, you may not
think that overlapping paths are a problem because you aren't aware that you have
overlapping domains.  If you use the <em><strong>ADFS Step-by-Step Guide</strong></em> to
put together your ADFS demo lab, you may find yourself using host names like this
to try out different application styles and using different TCP/IP ports for SSL to
split them up in IIS:
</p>
        <ul>
          <li>
            <font face="Courier New" color="#0000ff">https://apps.domain.com:8081/</font>
          </li>
          <li>
            <font face="Courier New" color="#0000ff">https://apps.domain.com:8082/</font>
          </li>
        </ul>
        <p>
While this makes things easy from the IIS perspective in terms of setting up multiple
sites and it makes it easier to deal with few host names (and less DNS and certificate
mucking around), remember that <strong><em>the browser treats those two hosts as being
the same thing for cookie purposes</em></strong>.  You now have overlapping domains. 
Therefore, it simply falls to the cookie path to make a distinction between them. 
If you use a path like:
</p>
        <ul>
          <li>
            <font face="Courier New" color="#0000ff">/claimsapp</font>
          </li>
          <li>
            <font face="Courier New" color="#0000ff">/tokenapp</font>
          </li>
        </ul>
        <p>
...for each one, you are fine, but if you naively put one or both of those apps in
the root, you will have problems if you try to do SSO between them with the previously
mentioned error.
</p>
        <p>
          <font size="4">Infinite Loop Errors and the Like</font>
        </p>
        <p>
The other problem we can easily create is the "infinite loop" problem or "same token
request within the last 20 seconds" problem on the federation server.  I've seen
this happen when we have a capitalization different between the browser URL and the
cookie path.  As we explained above, <strong><em>the cookie path is treated as
case sensitive by the browser</em></strong>, but IIS is generally very happy to treat
a URL folder or virtual directory path as case-insensitive.  The problem then
manifests itself in ADFS with an interaction like this:
</p>
        <ol>
          <li>
User logs into federation server after being redirected to do so by the application
they were trying to access 
</li>
          <li>
Federation server generates SAML token for resource application and redirects browser
to POST the token to that URL (<font face="Courier New" color="#0000ff">app.domain.com/site/</font>) 
</li>
          <li>
Resource application receives the token via POST, verifies it and issues the browser
a cookie with the token contents for use with subsequent visits.  The path in
the <strong><font face="Courier New">Set-Cookie</font></strong> header is <font face="Courier New" color="#0000ff">/Site</font>. 
App redirects the user back to itself with the exact URL originally requested. 
</li>
          <li>
Browser receives the cookie, but it is using a URL like <font face="Courier New" color="#0000ff">https://app.domain.com/<strong>s</strong>ite/default.aspx</font>,
not <font face="Courier New" color="#0000ff">https://app.domain.com/<strong>S</strong>ite/default.aspx</font>. 
Since those are clearly different (note the capital S!), <strong><em>the browser does
not include the authentication cookie in the request</em></strong>. 
</li>
          <li>
App receives the request from the browser without the cookie and decides "this guy
should log in if I'm going to allow access, so go back to my federation server, get
a token and I'll see you later" and redirects the user back to the federation server
with instructions to sign in. 
</li>
          <li>
Federation server is clever and notices that it just issued a token for this user
for this app a second ago or so and throws an error because it knows that something
just isn't right.</li>
        </ol>
        <p>
This one is a little subtle, but easily fixable.
</p>
        <p>
          <font size="5">Conclusion</font>
        </p>
        <p>
Cookies are at the heart and soul of how ADFS works (with the Passive Requester Profile
anyway), so understanding the rules that govern their behavior in the browser and
how ADFS expects you to use them will save you potentially hours or days of troubleshooting
misery.  
</p>
        <p>
          <font size="4">Tools for Viewing Headers and Cookies</font>
        </p>
        <p>
When working with ADFS (or really just about any web app I've found), having a way
to view the raw request and response headers associated with all of the traffic generated
by the browser and server is invaluable.  There are great plugins for IE (<a href="http://www.blunck.info/">ieHttpHeaders</a>) and
FireFox (<a href="http://livehttpheaders.mozdev.org/">Live Headers</a>) that do a
fine job of this and are free.  
</p>
        <p>
          <em>
            <font size="1">(edited March 4, 2007, to add some additional formatting, fix some
wording and add the section on viewing headers)</font>
          </em>
        </p>
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=d41ff2af-fa75-4252-8f93-37c88b019dbe" />
      </body>
      <title>Keep Your Cookies Straight When Using ADFS</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,d41ff2af-fa75-4252-8f93-37c88b019dbe.aspx</guid>
      <link>http://www.joekaplan.net/KeepYourCookiesStraightWhenUsingADFS.aspx</link>
      <pubDate>Sun, 04 Mar 2007 18:09:13 GMT</pubDate>
      <description>&lt;p&gt;
I've been using ADFS day in and day out for almost a year now and have run into a
fairly stunning number of issues.&amp;nbsp; Most of these are simple problems with simple
solutions, but they can cause hours or days of frustration to resolve.&amp;nbsp; One of
the main themes that seems to pervade these little doses of IT misery is based on
a misunderstanding of how cookies work and how ADFS uses cookies.&amp;nbsp; This post
is my attempt to gather some of the lessons I've learned and hopefully make your time
with ADFS a little easier.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&lt;font size=5&gt;How Cookies Work in Web Browsers&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Although many of us have a basic, foggy notion about what cookies do in web applications,
many of us don't know all of the little rules that govern their behavior.&amp;nbsp; I'll
try to run that down now based on my own understanding, which I believe is at least
technically accurate enough for the purposes of the rest of this article.&amp;nbsp; Feel
free to correct me if you know better or refer to the RFCs if you want more precision.
&lt;/p&gt;
&lt;p&gt;
Basically, a cookie is a small piece of textual data that is sent by a web server
to a web browser.&amp;nbsp; The job of the browser is to return this piece of data back
to the server when it makes another request to the server, based on the rules that
I'll detail shortly.&amp;nbsp; Cookies are generally used in web applications as a means
of maintaining state in the web server across multiple requests made by the browser.
&lt;/p&gt;
&lt;p&gt;
Cookies are implemented as well-known HTTP headers in the request data sent by the
browser and the response data sent.&amp;nbsp; The request header name is called &lt;font face="Courier New"&gt;&lt;strong&gt;Cookie&lt;/strong&gt;&lt;/font&gt; and
the response header name is &lt;strong&gt;&lt;font face="Courier New"&gt;Set-Cookie&lt;/font&gt;&lt;/strong&gt;.&amp;nbsp;
The server always initiates the usage of cookies by returning a response with a &lt;font face="Courier New"&gt;&lt;strong&gt;Set-Cookie&lt;/strong&gt;&lt;/font&gt; header
in it that contains the data and some other instructions.&amp;nbsp; The browser's job
is to then add a &lt;font face="Courier New"&gt;&lt;strong&gt;Cookie&lt;/strong&gt;&lt;/font&gt; header on
all subsequent requests to the server that contains exactly the data the server sent
in the &lt;strong&gt;&lt;font face="Courier New"&gt;Set-Cookie&lt;/font&gt;&lt;/strong&gt; header.&amp;nbsp; However,
exactly when the browser will add the &lt;font face="Courier New"&gt;&lt;strong&gt;Cookie&lt;/strong&gt;&lt;/font&gt; header
to its request is based on the other instructions in the &lt;font face="Courier New"&gt;&lt;strong&gt;Set-Cookie&lt;/strong&gt;&lt;/font&gt; header
and the rules for cookie behavior.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
First, let's examine the "other instructions".&amp;nbsp; The &lt;strong&gt;&lt;font face="Courier New"&gt;Set-Cookie&lt;/font&gt;&lt;/strong&gt; header
may contain these bits of info:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Name 
&lt;li&gt;
Value 
&lt;li&gt;
Domain (optional) 
&lt;li&gt;
Path (optional) 
&lt;li&gt;
Expires (optional) 
&lt;li&gt;
Secure flag (optional) 
&lt;li&gt;
HttpOnly flag (optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;font size=4&gt;Cookie Name and Value&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The Cookie Name is just what it sounds like.&amp;nbsp; Since a web app may use many different
cookies, this is how they can be distinguished.&amp;nbsp; The Cookie Value is just some
textual data.&amp;nbsp; It could be anything.&amp;nbsp; Oftentimes, it may contain some data
that has been encrypted that the browser can't even interpret it--only the server
can.&amp;nbsp; This is not a problem.&amp;nbsp; The data is for the server anyway.&amp;nbsp; The
browser's job is to&amp;nbsp;dutifully sending it back to the server, not understand it.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;Cookie Expires, Secure and HttpOnly&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
I'll skip ahead to the last three, as they easy to explain and not terribly problematic
(for our purposes).&amp;nbsp; The&amp;nbsp;optional Expires field&amp;nbsp;may contain&amp;nbsp;a
date/time value that tells the browser when to stop sending the cookie back to the
server.&amp;nbsp; This one is interesting because it alone determines whether a cookie
is a &lt;strong&gt;session cookie&lt;/strong&gt; or a &lt;strong&gt;file-based cookie&lt;/strong&gt;.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
If there is no expiration specified, the cookie defaults to a session cookie and will
be returned as long as the browser session continues.&amp;nbsp; In IE and FireFox (and
probably most other browsers on Windows), the session is basically the duration that
the browser &lt;em&gt;process&lt;/em&gt; is open.&amp;nbsp; Note that a browser process may span many
windows and may originate in a non-obvious place like an email or an instant messenger
client, so you may sometimes be surprised to see a cookie being sent back to a server
even after a window was closed (or seemingly all windows for that matter!).&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
If the expiration date is set, then the cookie is "file-based" and will be written
to disk.&amp;nbsp; It will survive across multiple browser processes being launched and
stopped.&amp;nbsp; The browser will continue to send it until the expiration time is exceeded.
&lt;/p&gt;
&lt;p&gt;
The Secure flag instructs the browser to only return the cookie back to the server
if the request uses the HTTPS (SSL) protocol.&amp;nbsp; This flag is often used when the
cookie contains sensitive data that could be useful by a bad guy if it was intercepted
on the wire.&amp;nbsp; I consider it to be bad practice to ever use any kind of forms-based
authentication cookie without the Secure flag set, although this then requires SSL.&amp;nbsp;
If you are serious about security, you use SSL for secure websites.&amp;nbsp; End of story.
&lt;/p&gt;
&lt;p&gt;
The HttpOnly flag is the new guy and not all browsers support it (although many do).&amp;nbsp;
It basically says that this cookie will only be sent on the wire.&amp;nbsp; The browser
will not allow the cookie to show up in the browser's Document Object Model (DOM)
cookie collection.&amp;nbsp; This prevents scripts from being able to view and manipulate
the cookie and can help prevent some kinds of cross-site scripting (XSS) attacks.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;Cookie Domain&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
For our purposes, The Cookie Domain and Path are the most interesting values, as this
is the heart of all of the trouble in ADFS, so we cover them last.&amp;nbsp; The domain
specifies which hosts the browser will replay the cookie to.&amp;nbsp; If the domain is
not specified, the browser will only replay the cookie to host that sent the &lt;font face="Courier New"&gt;&lt;strong&gt;Set-Cookie&lt;/strong&gt;&lt;/font&gt; header
in the first place.&amp;nbsp; Here, the host is determined by the host portion of the
URL.&amp;nbsp; For example, in&amp;nbsp;&lt;a href="http://www.joekaplan.net/default.aspx"&gt;http://www.joekaplan.net/default.aspx&lt;/a&gt;,
the host is &lt;font face="Courier New" color=#0000ff&gt;www.joekaplan.net&lt;/font&gt;.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Domains can also be specified hierarchically.&amp;nbsp; I could set the cookie domain
to &lt;font face="Courier New" color=#0000ff&gt;.joekaplan.net&lt;/font&gt; and then my browser
would return the cookie to any host within the &lt;font face="Courier New" color=#0000ff&gt;joekaplan.net&lt;/font&gt; DNS
namespace such as &lt;font face="Courier New" color=#0000ff&gt;www.joekaplan.net&lt;/font&gt;, &lt;font face="Courier New" color=#0000ff&gt;blogs.joekaplan.net&lt;/font&gt; and &lt;font face="Courier New" color=#0000ff&gt;junk.joekaplan.net&lt;/font&gt; (neither
of which exist in the latter two examples, but that isn't important).
&lt;/p&gt;
&lt;p&gt;
One might wonder if one can set a cookie for a domain other than the domain of the
host.&amp;nbsp; The answer is "it depends", but usually no.&amp;nbsp; As one can imagine,
this could (and has!) lead to all kinds of crazy hacking where one site writes over
another site's cookies.&amp;nbsp; In IE, the ability to do this is locked down by the
various security levels and assigned by zone.&amp;nbsp; I haven't seen many legitimate
uses for such a design personally, so I'm happy this is restricted now.
&lt;/p&gt;
&lt;p&gt;
Another important picky detail about the domain value is that it doesn't consider
the port component of the hostname in the URL.&amp;nbsp; Basically, this means that it
treats the host &lt;font face="Courier New" color=#0000ff&gt;www.joekaplan.net:80&lt;/font&gt; and &lt;font face="Courier New" color=#0000ff&gt;www.joekaplan.net:8080&lt;/font&gt; as &lt;strong&gt;&lt;em&gt;the
same host&lt;/em&gt;&lt;/strong&gt;, even if those map to completely different websites on your
web server.&amp;nbsp; This can lead to surprises.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;Cookie Path&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The final modifier is the Path.&amp;nbsp; The path value is like the domain, except that
is specifies the scope in the path hierarchy that the cookie will be replayed to.&amp;nbsp;
Here, the path is the part of the URL that comes after the host name.&amp;nbsp; If the
path is set to &lt;font face="Courier New" color=#0000ff&gt;/&lt;/font&gt;, then the cookie will
be replayed to any part of the hierarchy of the website.&amp;nbsp; If the path is set
to &lt;font face="Courier New" color=#0000ff&gt;/site&lt;/font&gt;, then the cookie will only
be replayed to requests for URLs at or below &lt;font face="Courier New" color=#0000ff&gt;/site&lt;/font&gt;.
&lt;/p&gt;
&lt;p&gt;
One tricky detail with the path value is that it is &lt;strong&gt;&lt;em&gt;case-sensitive&lt;/em&gt;&lt;/strong&gt;.&amp;nbsp;
If you set the path to &lt;font face="Courier New" color=#0000ff&gt;/site&lt;/font&gt; and your
URL is &lt;font face="Courier New" color=#0000ff&gt;http://www.joekaplan.net/Site/default.aspx&lt;/font&gt; (note
the capital "S"), guess what?&amp;nbsp; The cookie will not be returned with the request!&amp;nbsp;
This little gotcha can easily confound IIS developers, as IIS is generally quite happy
to treat folders and virtual directories as case-insensitive.&amp;nbsp; Developers on
"other" web server platforms where URLs (and file names) are case-sensitive tend to
be a little more hip to this. :)
&lt;/p&gt;
&lt;p&gt;
&lt;font size=5&gt;A Brief Tour of the ADFS Cookies&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
ADFS, like most other HTTP authentication protocols that don't use the built in HTTP
authentication specifications (Basic, Digest, Negotiate, Kerberos, NTLM, etc.), use
cookies for a lot of stuff.&amp;nbsp; There are three primary cookies to know about:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Authentication/Token cookie (&lt;font face="Courier New" color=#0000ff&gt;_WebSsoAuth&lt;/font&gt;) 
&lt;li&gt;
Home Realm Cookie (&lt;font face="Courier New" color=#0000ff&gt;_LSRealm&lt;/font&gt;) 
&lt;li&gt;
Logout Cookie (&lt;font face="Courier New" color=#0000ff&gt;_LSCleanup&lt;/font&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Let's take each in turn.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;Authentication/Token Cookie&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The &lt;font face="Courier New" color=#0000ff&gt;_WebSsoAuth&lt;/font&gt; cookie is certainly
the most important one, as that is the cookie that represents the user's login to
a federation resource.&amp;nbsp; This cookie is always a session cookie, in that the Expires
field is never set, so it goes away when the browser process does.&amp;nbsp; Expiration
of this cookie is handled by timestamps set in the data in the cookie itself and is
a programmatic feature of the protocol and is not related to how the browser treats
cookie expiration.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
The cookie basically contains the SAML 1.1 token issued by a federation server that
allows access to a specific resource.&amp;nbsp; The format of the cookie for ADFS is in
some crazy compressed format that MS came up with that isn't documented, but that
is supposedly cool because the WS-Federation PRP spec doesn't actually contain any
details about what this should look like and leaves it implementation specific.&amp;nbsp;
These cookies are only consumed by the server/app that issued them (hopefully!), so
this isn't a big deal.&amp;nbsp; Sometimes you may see a &lt;font face="Courier New" color=#0000ff&gt;_WebSsoAuth0&lt;/font&gt; cookie
or additional numbering.&amp;nbsp; This can happen if the SAML token is very large and
the compressed size of the XML in the SAML token may exceed the allowed size of a
cookie.&amp;nbsp; ADFS breaks these up for you to overcome this.&amp;nbsp; This is a picky
and unimportant detail for our discussion, but I figured I'd mention it in case you
saw it and were curious.
&lt;/p&gt;
&lt;p&gt;
The &lt;font face="Courier New"&gt;&lt;strong&gt;Set-Cookie&lt;/strong&gt;&lt;/font&gt; header for this cookie
usually looks something like this (data clipped for brevity):
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New" color=#0000ff&gt;Set-Cookie: _WebSsoAuth=eNrNWWuTqkgS9acYzpfd6LV5qAhGd8cWDxUVFMVnbMREASWiQ.....CdagA;
path=/adfs/ls/; secure; HttpOnly&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
In this case, this is the authentication cookie issued by the federation server itself.&amp;nbsp;
In ADFS, each federation server the user logs in to (at least one, maybe two if there
is an account partner/resource partner set up) will issue&amp;nbsp;a &lt;font face="Courier New" color=#0000ff&gt;_WebSsoAuth&lt;/font&gt; cookie.&amp;nbsp;
Additionally, each application that the user visits will issue a &lt;font face="Courier New" color=#0000ff&gt;_WebSsoAuth&lt;/font&gt; cookie
that is specific to the application.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Each &lt;font face="Courier New" color=#0000ff&gt;_WebSsoAuth&lt;/font&gt; cookie is &lt;em&gt;different&lt;/em&gt; and &lt;em&gt;is
intended only for the app/server that issued it&lt;/em&gt;.&amp;nbsp; However, you probably
noticed&amp;nbsp;how they all have the same name.&amp;nbsp; Because they all have the same
name, they must different by &lt;em&gt;domain&lt;/em&gt; and &lt;em&gt;path&lt;/em&gt; so that the browser
will know which cookie to send to which app/server.&amp;nbsp; If you've ever configured
an ADFS token-based or claims-based application, you will have noticed that you are
required to specify the domain and path for the cookie when configuring the application.&amp;nbsp;
All it takes is a naive mistake with this configuration to cause the browser to start
sending the wrong cookie to the wrong place and ADFS chaos ensues.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;Home Realm Cookie&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The &lt;font face="Courier New" color=#0000ff&gt;_LSRealm&lt;/font&gt; cookie is a file-based
cookie issued by the resource federation server after you have successfully logged
in that specifies the federation server URI (usually &lt;font face="Courier New"&gt;urn:federation:foo&lt;/font&gt; or
something) of the server that authenticated you.&amp;nbsp; This is done so that the resource
federation server doesn't have to prompt you for your home organization again if it
has multiple potential partners.&amp;nbsp; We already discussed a little bit about these
values and home realm discovery query strings in a &lt;a href="http://www.joekaplan.net/NoteToUrnfederationself.aspx"&gt;post&lt;/a&gt; last
summer, so I won't get into much more detail.&amp;nbsp; These things rarely cause trouble
except that you have to clear your cookies if you want to get a resource federation
server to prompt you for your home realm again after you log in the first time.&amp;nbsp;
They are issued for one month as I recall; I'm too lazy to check for certain right
now.&amp;nbsp; :)
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;Logout Cookie&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The &lt;font face="Courier New" color=#0000ff&gt;_LSCleanup&lt;/font&gt; cookie assists in the
logout process by keeping track of which federation servers and applications you've
visited.&amp;nbsp; When ADFS does a log out, it attempts to "drain the swamp" by logging
you out of &lt;strong&gt;everything&lt;/strong&gt;.&amp;nbsp; To do this, the built-in logout page
attempts to visit the logout URL for every federation server you've visited and every
app you've visited.&amp;nbsp; These logout URLs set the &lt;font face="Courier New" color=#0000ff&gt;_WebSsoAuth&lt;/font&gt; cookie
value for the cookies they issued to "null".&amp;nbsp; This cookie is also a session cookie.&amp;nbsp;
These cookies can get screwed up just like the authentication cookies, but usually
this fact never comes up because once the authentication cookies are hosed, things
tend to break before you ever try to log out.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=5&gt;Common ADFS Problems Caused by Incorrect Cookie Settings&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
There are two ADFS problems I've seen frequently that cause much pain that are related
to cookie problems and probably some variants that I'm forgetting:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Invalid SAML Audience 
&lt;li&gt;
Infinite Loop Detected&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;font size=4&gt;Invalid SAML Audience&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
This occurs when one ADFS application get's another ADFS application's cookie.&amp;nbsp;
Like I said before, each application has an application-specific cookie and there
is a piece of data in the SAML token called the &lt;em&gt;audience&lt;/em&gt; that says exactly
where the cookie was supposed to go.&amp;nbsp; This is identified by the application's
configured URL in the trust policy and the web site.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
There are a variety of ways you can create this error.&amp;nbsp; One easy way is by setting
the cookie domain to something like &lt;font face="Courier New" color=#0000ff&gt;.domain.com&lt;/font&gt; and
having your apps set up with host names like &lt;font face="Courier New" color=#0000ff&gt;app1.domain.com&lt;/font&gt; and &lt;font face="Courier New" color=#0000ff&gt;app2.domain.com&lt;/font&gt;.&amp;nbsp;
Since these are both basically children of &lt;font face="Courier New" color=#0000ff&gt;.domain.com&lt;/font&gt;,
the browser will happily send a &lt;font face="Courier New" color=#0000ff&gt;_WebSsoAuth&lt;/font&gt; cookie
to &lt;strong&gt;app2&lt;/strong&gt; that &lt;strong&gt;app1&lt;/strong&gt; issued if the paths are the same.&amp;nbsp;
Since the path is often set to &lt;font face="Courier New" color=#0000ff&gt;/&lt;/font&gt;, this
is not uncommon.&amp;nbsp; You can also have pseudo-chaos that is even more difficult
to debug if the path's aren't the same but contain some overlap in hierarchy.
&lt;/p&gt;
&lt;p&gt;
I'm still trying to figure out a reason why you would ever set the cookie domain in
an ADFS system.&amp;nbsp; Generally, you only ever want an ADFS cookie going back to the
host that issued it, so why not leave it at the default setting of "null"?&amp;nbsp; In
my experience, nothing but trouble ever comes from setting the domain.&amp;nbsp; If you
think of a use case for setting this, please let me know.
&lt;/p&gt;
&lt;p&gt;
I also mentioned overlapping paths.&amp;nbsp; These are a significant cause of trouble.&amp;nbsp;
Let's say you have an app at the root of the site &lt;font face="Courier New" color=#0000ff&gt;/&lt;/font&gt; and
an app below that &lt;font face="Courier New" color=#0000ff&gt;/Site&lt;/font&gt;.&amp;nbsp; Basically,
if they have the same host name, &lt;em&gt;you can't do that in ADFS&lt;/em&gt;.&amp;nbsp; They need
to be strict siblings like &lt;font face="Courier New" color=#0000ff&gt;/Site1&lt;/font&gt; and &lt;font face="Courier New" color=#0000ff&gt;/Site2&lt;/font&gt;.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Overlapping paths can show up in subtle ways as well.&amp;nbsp; Sometimes, you may not
think that overlapping paths are a problem because you aren't aware that you have
overlapping domains.&amp;nbsp; If you use the &lt;em&gt;&lt;strong&gt;ADFS Step-by-Step Guide&lt;/strong&gt;&lt;/em&gt; to
put together your ADFS demo lab, you may find yourself using host names like this
to try out different application styles and using different TCP/IP ports for SSL to
split them up in IIS:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;font face="Courier New" color=#0000ff&gt;https://apps.domain.com:8081/&lt;/font&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;font face="Courier New" color=#0000ff&gt;https://apps.domain.com:8082/&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
While this makes things easy from the IIS perspective in terms of setting up multiple
sites and it makes it easier to deal with few host names (and less DNS and certificate
mucking around), remember that &lt;strong&gt;&lt;em&gt;the browser treats those two hosts as being
the same thing for cookie purposes&lt;/em&gt;&lt;/strong&gt;.&amp;nbsp; You now have overlapping domains.&amp;nbsp;
Therefore, it simply falls to the cookie path to make a distinction between them.&amp;nbsp;
If you use a path like:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;font face="Courier New" color=#0000ff&gt;/claimsapp&lt;/font&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;font face="Courier New" color=#0000ff&gt;/tokenapp&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
...for each one, you are fine, but if you naively put one or both of those apps in
the root, you will have problems if you try to do SSO between them with the previously
mentioned error.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;Infinite Loop Errors and the Like&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The other problem we can easily create is the "infinite loop" problem or "same token
request within the last 20 seconds" problem on the federation server.&amp;nbsp; I've seen
this happen when we have a capitalization different between the browser URL and the
cookie path.&amp;nbsp; As we explained above, &lt;strong&gt;&lt;em&gt;the cookie path is treated as
case sensitive by the browser&lt;/em&gt;&lt;/strong&gt;, but IIS is generally very happy to treat
a URL folder or virtual directory path as case-insensitive.&amp;nbsp; The problem then
manifests itself in ADFS with an interaction like this:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
User logs into federation server after being redirected to do so by the application
they were trying to access 
&lt;li&gt;
Federation server generates SAML token for resource application and redirects browser
to POST the token to that URL (&lt;font face="Courier New" color=#0000ff&gt;app.domain.com/site/&lt;/font&gt;) 
&lt;li&gt;
Resource application receives the token via POST, verifies it and issues the browser
a cookie with the token contents for use with subsequent visits.&amp;nbsp; The path in
the &lt;strong&gt;&lt;font face="Courier New"&gt;Set-Cookie&lt;/font&gt;&lt;/strong&gt; header is &lt;font face="Courier New" color=#0000ff&gt;/Site&lt;/font&gt;.&amp;nbsp;
App redirects the user back to itself with the exact URL originally requested. 
&lt;li&gt;
Browser receives the cookie, but it is using a URL like &lt;font face="Courier New" color=#0000ff&gt;https://app.domain.com/&lt;strong&gt;s&lt;/strong&gt;ite/default.aspx&lt;/font&gt;,
not &lt;font face="Courier New" color=#0000ff&gt;https://app.domain.com/&lt;strong&gt;S&lt;/strong&gt;ite/default.aspx&lt;/font&gt;.&amp;nbsp;
Since those are clearly different (note the capital S!), &lt;strong&gt;&lt;em&gt;the browser does
not include the authentication cookie in the request&lt;/em&gt;&lt;/strong&gt;. 
&lt;li&gt;
App receives the request from the browser without the cookie and decides "this guy
should log in if I'm going to allow access, so go back to my federation server, get
a token and I'll see you later" and redirects the user back to the federation server
with instructions to sign in. 
&lt;li&gt;
Federation server is clever and notices that it just issued a token for this user
for this app a second ago or so and throws an error because it knows that something
just isn't right.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
This one is a little subtle, but easily fixable.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=5&gt;Conclusion&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Cookies are at the heart and soul of how ADFS works (with the Passive Requester Profile
anyway), so understanding the rules that govern their behavior in the browser and
how ADFS expects you to use them will save you potentially hours or days of troubleshooting
misery.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;Tools for Viewing Headers and Cookies&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
When working with ADFS (or really just about any web app I've found), having a way
to view the raw request and response headers associated with all of the traffic generated
by the browser and server is invaluable.&amp;nbsp; There are great plugins for IE (&lt;a href="http://www.blunck.info/"&gt;ieHttpHeaders&lt;/a&gt;)&amp;nbsp;and
FireFox (&lt;a href="http://livehttpheaders.mozdev.org/"&gt;Live Headers&lt;/a&gt;) that do a
fine job of this and are free.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;font size=1&gt;(edited March 4, 2007, to add some additional formatting, fix some
wording and add the section on viewing headers)&lt;/font&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=d41ff2af-fa75-4252-8f93-37c88b019dbe" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,d41ff2af-fa75-4252-8f93-37c88b019dbe.aspx</comments>
      <category>Identity Federation</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=81dcfdbd-ec4e-4a19-aca5-0c0e35ad00bf</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,81dcfdbd-ec4e-4a19-aca5-0c0e35ad00bf.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,81dcfdbd-ec4e-4a19-aca5-0c0e35ad00bf.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=81dcfdbd-ec4e-4a19-aca5-0c0e35ad00bf</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Both of the readers of my blog probably think of me primarily as a .NET LDAP/Security/ADFS
guy, and that's fine with me.  The vast majority of my posts aren't about my
personal life, so that's what I seem like.  However, those who know me better
know that I also play drums and have played in a few bands in my day.
</p>
        <p>
I went on hiatus from doing any serious band stuff after my son was born and thought
I was pretty much done.  There does come a time when one packs that sort of thing
in, although I'm not certain what that threshold is.
</p>
        <p>
Apparently I haven't quite hit that yet, because I was recently lured back into playing
in a band again.  I am now the drummer for <a href="http://www.nadnavillus.com/arriver/">Arriver</a> (replacing
the dude in the left in the photo), which is basically a metal project started by
Dan MacAdam, the guitarist from my previous band, <a href="http://www.allmusic.com/cg/amg.dll?p=amg&amp;sql=11:sbddyl42xpvb">Viza-Noir</a>,
and Dan and Rob Sullivan.
</p>
        <p>
I've played with Dan M. for years and have also played with the Sullivan brothers
for years as well, although never in a serious songwriting type of band.  The
Sullivans and I, along with Jimmy "Bigstacks" Grabowski, formed the core of the legendary
Dave LaCrone and the Mistletones, a band that existed only to play a rather insane
annual holiday party.  The 'tones also played quite a few of my friends' weddings
and a prom in a cover band capacity.
</p>
        <p>
Dan M. played with the Sullivans and their other brother Andy in a straight up bluegrass
band called Skeeter Pete and the Sullivan Mountain Boys, which I was fortunate enough
to record a few years ago.  Them boys can sing and they pick pretty well too. 
:)  I also recorded <a href="http://www.allmusic.com/cg/amg.dll?p=amg&amp;sql=10:5rfnzfo2eh8k">a
record</a> for Dan Sullivan for his <a href="http://www.nadnavillus.com">Nad Navillus</a> project,
which was a singer/songwriter project featuring Dan's virtuoso guitar playing and
some more introspective material.
</p>
        <p>
The Sullivan brothers also play in one of the most ambitious rock bands in Chicago, <a href="http://butchershopquartet.com/">the
Butcher Shop Quartet</a>.  The BSQ plays arrangements of contemporary classical
pieces for rock band (generally 2x guitar, bass and drums).  They are most famous
for their truly impressive rendering of Stravinsky's Rite of Spring, something that
has to be heard to be believed.
</p>
        <p>
You are also plenty likely to find Rob playing bass at a bar near you with the Blue
Line Riders, a 6 piece honky tonk band with one of the most impressive set lists I've
ever seen.
</p>
        <p>
Arriver is a metal band.  This takes me back to my childhood, as that's what
I grew up listening to in the South as a kid (didn't everyone?).  However, metal
has changed a lot since I was into it.  I had pretty much switched to indy rock
by the time thrash metal and speed metal transformed the genre.  We now have
blast beats, crazy time signatures and demonic vocals to round out the power chords
and "widdly-widdly" guitar solos.  Sick double kick chops are assumed as the
price of admission.  I've got a lot of catching up to do. :)
</p>
        <p>
I actually got a double bass drum pedal when I was 16, as all the cool kids had one
and I wanted one too.  I used it for years in various band projects, although
I never learned how to do the fast metal rolls that you need to have to play this
stuff.  20 years later, I sill have the same DW 5000 double kick pedal. 
It works ok, but I might need an update.  It is pretty lose and the sprockets
are all worn down.
</p>
        <p>
China cymbals, often frowned on in indy rock as being too "something" (having to do
with uncool I'm sure) are welcome in metal, so some of my other 20 year old gear is
geting a ride again.  I'm actually using 2 on my current set, something I've
never done before (a 20+ year old 19" K china and a 10 year old 22" swish knocker
with rivets that I bought when they reissued them a few years ago; obnoxious cymbal!). 
This part I like quite a lot.  I haven't yet gone over the top with my set-up,
still just using a 4 piece kit with 4 cymbals, but the 2 china thing is super
fun.  I also only have 1 crash, which is weird for me.  Maybe I'll round
this thing out with something that goes "ping".  
</p>
        <p>
The odd time signatures are things I'm pretty used to, so that's less of a struggle. 
I'm not going to sound like <a href="http://www.meshuggah.net/">Meshuggah</a> anytime
soon (although the same can be said for a lot of others who are trying way harder
than we are), but I know how to play in 5 and 7.  My double kick and blast beats
are a little embarassing right now, but that will motivate me to get better. 
Arriver has as much appreciation for <a href="http://www.manowar.com/">Man-O-War</a> as
we do for the cerebral stuff and is pretty song-oriented in general, so I doubt we'll
ever go over the top into pure inaccessibility.
</p>
        <p>
If you are 30+ drummer getting back into music and have decided to add blast beats
and blazing double kick into your repertoire, drop me a line and let me know how you
did it.  :)
</p>
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=81dcfdbd-ec4e-4a19-aca5-0c0e35ad00bf" />
      </body>
      <title>Now I Rock Again</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,81dcfdbd-ec4e-4a19-aca5-0c0e35ad00bf.aspx</guid>
      <link>http://www.joekaplan.net/NowIRockAgain.aspx</link>
      <pubDate>Sat, 27 Jan 2007 16:00:29 GMT</pubDate>
      <description>&lt;p&gt;
Both of the readers of my blog probably think of me primarily as a .NET LDAP/Security/ADFS
guy, and that's fine with me.&amp;nbsp; The vast majority of my posts aren't about my
personal life, so that's what I seem like.&amp;nbsp; However, those who know me better
know that I also play drums and have played in a few bands in my day.
&lt;/p&gt;
&lt;p&gt;
I went on hiatus from doing any serious band stuff after my son was born and thought
I was pretty much done.&amp;nbsp; There does come a time when one packs that sort of thing
in, although I'm not certain what that threshold is.
&lt;/p&gt;
&lt;p&gt;
Apparently I haven't quite hit that yet, because I was recently lured back into playing
in a band again.&amp;nbsp; I am now the drummer for &lt;a href="http://www.nadnavillus.com/arriver/"&gt;Arriver&lt;/a&gt; (replacing
the dude in the left in the photo), which is basically a metal project started by
Dan MacAdam, the guitarist from my previous band, &lt;a href="http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;sql=11:sbddyl42xpvb"&gt;Viza-Noir&lt;/a&gt;,
and Dan and Rob Sullivan.
&lt;/p&gt;
&lt;p&gt;
I've played with Dan M. for years and have also played with the Sullivan brothers
for years as well, although never in a serious songwriting type of band.&amp;nbsp; The
Sullivans and I, along with Jimmy "Bigstacks" Grabowski, formed the core of the legendary
Dave LaCrone and the Mistletones, a band that existed only to play a rather insane
annual holiday party.&amp;nbsp; The 'tones also played quite a few of my friends' weddings
and a prom in a cover band capacity.
&lt;/p&gt;
&lt;p&gt;
Dan M. played with the Sullivans and their other brother Andy in a straight up bluegrass
band called Skeeter Pete and the Sullivan Mountain Boys, which I was fortunate enough
to record a few years ago.&amp;nbsp; Them boys can sing and they pick pretty well too.&amp;nbsp;
:)&amp;nbsp; I also recorded &lt;a href="http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;sql=10:5rfnzfo2eh8k"&gt;a
record&lt;/a&gt; for Dan Sullivan for his &lt;a href="http://www.nadnavillus.com"&gt;Nad Navillus&lt;/a&gt; project,
which was a singer/songwriter project featuring Dan's virtuoso guitar playing and
some more introspective material.
&lt;/p&gt;
&lt;p&gt;
The Sullivan brothers also play in one of the most ambitious rock bands in Chicago, &lt;a href="http://butchershopquartet.com/"&gt;the
Butcher Shop Quartet&lt;/a&gt;.&amp;nbsp; The BSQ plays arrangements of contemporary classical
pieces for rock band (generally 2x guitar, bass and drums).&amp;nbsp; They are most famous
for their truly impressive rendering of Stravinsky's Rite of Spring, something that
has to be heard to be believed.
&lt;/p&gt;
&lt;p&gt;
You are also plenty likely to find Rob playing bass at a bar near you with the Blue
Line Riders, a 6 piece honky tonk band with one of the most impressive set lists I've
ever seen.
&lt;/p&gt;
&lt;p&gt;
Arriver is a metal band.&amp;nbsp; This takes me back to my childhood, as that's what
I grew up listening to in the South as a kid (didn't everyone?).&amp;nbsp; However, metal
has changed a lot since I was into it.&amp;nbsp; I had pretty much switched to indy rock
by the time thrash metal and speed metal transformed the genre.&amp;nbsp; We now have
blast beats, crazy time signatures and demonic vocals to round out the power chords
and "widdly-widdly" guitar solos.&amp;nbsp; Sick double kick chops are assumed as the
price of admission.&amp;nbsp; I've got a lot of catching up to do. :)
&lt;/p&gt;
&lt;p&gt;
I actually got a double bass drum pedal when I was 16, as all the cool kids had one
and I wanted one too.&amp;nbsp; I used it for years in various band projects, although
I never learned how to do the fast metal rolls that you need to have to play this
stuff.&amp;nbsp; 20 years later, I sill have the same DW 5000 double kick pedal.&amp;nbsp;
It works ok, but I might need an update.&amp;nbsp; It is pretty lose and the sprockets
are all worn down.
&lt;/p&gt;
&lt;p&gt;
China cymbals, often frowned on in indy rock as being too "something" (having to do
with uncool I'm sure) are welcome in metal, so some of my other 20 year old gear is
geting a ride again.&amp;nbsp; I'm actually using 2 on my current set, something I've
never done before (a 20+ year old 19" K china and a 10 year old 22" swish knocker
with rivets that I bought when they reissued them a few years ago; obnoxious cymbal!).&amp;nbsp;
This part I like quite a lot.&amp;nbsp; I haven't yet gone over the top with my set-up,
still just using a&amp;nbsp;4 piece kit with 4 cymbals, but the 2 china thing is super
fun.&amp;nbsp; I also only have 1 crash, which is weird for me.&amp;nbsp; Maybe I'll round
this thing out with something that goes "ping".&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
The odd time signatures are things I'm pretty used to, so that's less of a struggle.&amp;nbsp;
I'm not going to sound like &lt;a href="http://www.meshuggah.net/"&gt;Meshuggah&lt;/a&gt; anytime
soon (although the same can be said for a lot of others who are trying way harder
than we are), but I know how to play in 5 and 7.&amp;nbsp; My double kick and blast beats
are a little embarassing right now, but that will motivate me to get better.&amp;nbsp;
Arriver has as much appreciation for &lt;a href="http://www.manowar.com/"&gt;Man-O-War&lt;/a&gt; as
we do for the cerebral stuff and is pretty song-oriented in general, so I doubt we'll
ever go over the top into pure inaccessibility.
&lt;/p&gt;
&lt;p&gt;
If you are 30+ drummer getting back into music and have decided to add blast beats
and blazing double kick into your repertoire, drop me a line and let me know how you
did it.&amp;nbsp; :)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=81dcfdbd-ec4e-4a19-aca5-0c0e35ad00bf" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,81dcfdbd-ec4e-4a19-aca5-0c0e35ad00bf.aspx</comments>
      <category>General</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=3d6db311-dd87-4148-9d56-d7f677867c77</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,3d6db311-dd87-4148-9d56-d7f677867c77.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,3d6db311-dd87-4148-9d56-d7f677867c77.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=3d6db311-dd87-4148-9d56-d7f677867c77</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
After some lofty goals of getting this blog jumpstarted back in the fall, I did just
the opposite and let it drop into a black hole.  To all of my faithful readers,
I humbly apologize.
</p>
        <p>
As part of an effort to gain some momentum again, I thought I'd try to rattle off
a quick post here.  Today's topic is intended as a continuation of my article
on series of <a href="http://www.joekaplan.net/ATaleOfTwoLDAPStacks.aspx">"things
you can do in System.DirectoryServices.Protocols that you can't do in System.DirectoryServices"</a>. 
We already discussed the ability to do <a href=" http://www.joekaplan.net/AnotherSDSPonlyFeatureDigestAuthentication.aspx">Digest
authentication</a> and <a href="http://www.joekaplan.net/Example1ForSDSPSSLCertificates.aspx">process
server certificates</a>.  Today's topic shows how to use S.DS.P's ability to
invoke arbitrary extended operations using the ExtendedRequest/ExtendedResponse message
types.
</p>
        <p>
Briefly, extended requests in LDAP allow directory vendors to create whole new types
of operations that are not built in to the base LDAP specification.  Essentially,
the directory advertises that it supports a specific type of extended operation via
the "supportedExtension" attribute in RootDSE (not loaded by default, so make sure
you add it to your attribute list!).  If the client knows how to pass in the
data to the extension operation and knows how to interpret the results, it can invoke
the extended operation.  If not, too bad.
</p>
        <p>
One such common extended LDAP operation is the "Who Am I?" operation as defined by <a href="http://tools.ietf.org/html/rfc4532">RFC
4532</a>.  Basically, the intent is to allow the LDAP client to issue the extended
operation and receive a response that provides information about the identity of the
user who is currently authenticated to the current LDAP connection via a previous
bind operation (if a bind was performed).  
</p>
        <p>
Interestingly, ADAM now supports the "Who Am I?" operation, as will Active Directory
in the Longhorn server time frame.  As such, it makes an excellent target for
investigation here as "Who Am I?" currently has no strongly typed wrapper in S.DS.P
(yet) and is also exceedingly easy to both call and interpret the returned results. 
I just learned about the existence of this thing via a thread on the exceedingly great
mailing list "activedir.org".  I figured I should go ahead and give it a whirl
to see how it works.  
</p>
        <p>
Without further ado, I humbly submit a few lines of code that demonstrate binding
to an ADAM instance on localhost on the default port (389) as the currently logged
on user and then invoking the "Who Am I?" extended request to find out my own Windows
user name (in case I forgot it :)).  
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> AdamWhoAmI<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Main()<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> (LdapConnection
con <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> LdapConnection(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"localhost"</span>))<br />
        {<br />
            con.Bind(); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//use
default credentials. Current user can bind to ADAM...</span><br />
            <br />
            ExtendedRequest
whoami <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> ExtendedRequest(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"1.3.6.1.4.1.4203.1.11.3"</span>); </span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//whoami
OID shown above, as per RFC</span></span>
        </p>
        <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          </span>
          <p>
            <br />
            ExtendedResponse
whoamiResult <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> (ExtendedResponse)
con.SendRequest(whoami);<br />
            Console.WriteLine(System.Text.Encoding.UTF8.GetString(whoamiResult.ResponseValue));
</p>
          <p>
            //the result is
a simple byte array that happens to contain UTF8 text<br />
        }<br />
        Console.ReadLine();<br />
    }<br />
}
</p>
        </span>
        <p>
Wow, pretty fancy stuff!  This actually compiled and ran on my very first try,
which usually doesn't work out.  As such, I feel confident in describing this
as "exceedingly simple".  On my machine, the result looks something like:
</p>
        <p>
          <font face="Courier New">u:machine\joe</font>
        </p>
        <p>
The interesting thing here is that this "just works" and it shows a semi-practical
thing you can do with this particular extensibility mechanism in LDAP that just happens
to not be exposed in System.DirectoryServices at all.  I'm sure there are some
practical uses for this, but the main point is just to show how to use this feature
with the simplest example possible.
</p>
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=3d6db311-dd87-4148-9d56-d7f677867c77" />
      </body>
      <title>ADAM WhoAmI Control in S.DS.P</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,3d6db311-dd87-4148-9d56-d7f677867c77.aspx</guid>
      <link>http://www.joekaplan.net/ADAMWhoAmIControlInSDSP.aspx</link>
      <pubDate>Thu, 25 Jan 2007 18:32:39 GMT</pubDate>
      <description>&lt;p&gt;
After some lofty goals of getting this blog jumpstarted back in the fall, I did just
the opposite and let it drop into a black hole.&amp;nbsp; To all of my faithful readers,
I humbly apologize.
&lt;/p&gt;
&lt;p&gt;
As part of an effort to gain some momentum again, I thought I'd try to rattle off
a quick post here.&amp;nbsp; Today's topic is intended as a continuation of my article
on series of &lt;a href="http://www.joekaplan.net/ATaleOfTwoLDAPStacks.aspx"&gt;"things
you can do in System.DirectoryServices.Protocols that you can't do in System.DirectoryServices"&lt;/a&gt;.&amp;nbsp;
We already discussed the ability to do &lt;a href=" http://www.joekaplan.net/AnotherSDSPonlyFeatureDigestAuthentication.aspx"&gt;Digest
authentication&lt;/a&gt; and &lt;a href="http://www.joekaplan.net/Example1ForSDSPSSLCertificates.aspx"&gt;process
server certificates&lt;/a&gt;.&amp;nbsp; Today's topic shows how to use S.DS.P's ability to
invoke arbitrary extended operations using the ExtendedRequest/ExtendedResponse message
types.
&lt;/p&gt;
&lt;p&gt;
Briefly, extended requests in LDAP allow directory vendors to create whole new types
of operations that are not built in to the base LDAP specification.&amp;nbsp; Essentially,
the directory advertises that it supports a specific type of extended operation via
the "supportedExtension" attribute in RootDSE (not loaded by default, so make sure
you add it to your attribute list!).&amp;nbsp; If the client knows how to pass in the
data to the extension operation and knows how to interpret the results, it can invoke
the extended operation.&amp;nbsp; If not, too bad.
&lt;/p&gt;
&lt;p&gt;
One such common extended LDAP operation is the "Who Am I?" operation as defined by &lt;a href="http://tools.ietf.org/html/rfc4532"&gt;RFC
4532&lt;/a&gt;.&amp;nbsp; Basically, the intent is to allow the LDAP client to issue the extended
operation and receive a response that provides information about the identity of the
user who is currently authenticated to the current LDAP connection via a previous
bind operation (if a bind was performed).&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Interestingly, ADAM now supports the "Who Am I?" operation, as will Active Directory
in the Longhorn server time frame.&amp;nbsp; As such, it makes an excellent target for
investigation here as "Who Am I?" currently has no strongly typed wrapper in S.DS.P
(yet)&amp;nbsp;and is also exceedingly easy to both call and interpret the returned results.&amp;nbsp;
I just learned about the existence of this thing via a thread on the exceedingly great
mailing list "activedir.org".&amp;nbsp; I figured I should go ahead and give it a whirl
to see how it works.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Without further ado, I humbly submit a few lines of code that demonstrate binding
to an ADAM instance on localhost on the default port (389) as the currently logged
on user and then invoking the "Who Am I?" extended request to find out my own Windows
user name (in case I forgot it :)).&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; AdamWhoAmI&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Main()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; (LdapConnection
con &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; LdapConnection(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"localhost"&lt;/span&gt;))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;con.Bind(); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//use
default credentials. Current user can bind to ADAM...&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ExtendedRequest
whoami &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; ExtendedRequest(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"1.3.6.1.4.1.4203.1.11.3"&lt;/span&gt;);&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//whoami
OID shown above, as per RFC&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;/span&gt; 
&lt;p&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ExtendedResponse
whoamiResult &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; (ExtendedResponse)
con.SendRequest(whoami);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(System.Text.Encoding.UTF8.GetString(whoamiResult.ResponseValue));
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //the result is
a simple byte array that happens to contain UTF8 text&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.ReadLine();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}
&lt;/span&gt;&gt;
&lt;p&gt;
Wow, pretty fancy stuff!&amp;nbsp; This actually compiled and ran on my very first try,
which usually doesn't work out.&amp;nbsp; As such, I feel confident in describing this
as "exceedingly simple".&amp;nbsp; On my machine, the result looks something like:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;u:machine\joe&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The interesting thing here is that this "just works" and it shows a semi-practical
thing you can do with this particular extensibility mechanism in LDAP that just happens
to not be exposed in System.DirectoryServices at all.&amp;nbsp; I'm sure there are some
practical uses for this, but the main point is just to show how to use this feature
with the simplest example possible.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=3d6db311-dd87-4148-9d56-d7f677867c77" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,3d6db311-dd87-4148-9d56-d7f677867c77.aspx</comments>
      <category>LDAP</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=668538b6-547f-4b96-af85-4f9d3a6baad2</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,668538b6-547f-4b96-af85-4f9d3a6baad2.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,668538b6-547f-4b96-af85-4f9d3a6baad2.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=668538b6-547f-4b96-af85-4f9d3a6baad2</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of my favorite softies, <a href="http://blogs.technet.com/efleis/default.aspx">Eric
Fleischman</a>, is doing <a href="http://blogs.technet.com/efleis/archive/2006/10/26/finding-the-lost-found-container-in-s-ds-p-or-anything-that-isn-t-adsi-really.aspx">some
S.DS.P programming</a> these days.  He demonstrates a useful technique, which
is how to do WKGUID searches to find well-known objects in AD or ADAM.  For those
not familiar with this, AD and ADAM have a set of "well-known" objects that the directory
always contains and applications may need to find to do reasonable things.  However,
the names of these objects may be internationalized, so it may not be possible to
find them by name across different implementations of the directory.  By referencing
them by the "well-known" GUID, a published value, you can always find them.
</p>
        <p>
One of the things we didn't do in our book was provide matching S.DS.P samples for
most of the techniques.  In fact, we barely covered it at all.  I still
have some regrets about this, although I also think we probably did the right thing. 
If the book had been 800 pages due to all the extra samples, that would have been
tough.  I do think there might be a place to supplement the material with online
materials at some point.  I'm not sure another print tome dedicated to the subject
would ever sell very well as the audience is probably limited and likely needs the
material less than than the audience we originally wrote the book for (I could be
wrong about this).  The internal debate continues...
</p>
        <p>
One of the things that Eric does hit on is the somewhat sad state of affairs of the
MSDN DS API documentation.  The S.DS.P docs are especially heinous, as they
include almost NO samples and even have some stuff documented as wrong or misleading. 
For example, the documentation for the <a href="http://blogs.technet.com/efleis/archive/2006/10/26/finding-the-lost-found-container-in-s-ds-p-or-anything-that-isn-t-adsi-really.aspx">DistinguishedName</a> property
on the SearchRequest class doesn't even succeed in identifying that as the search
BASE of the search, instead calling it the "object to search for".  If it wasn't
for the fact that there is no other obvious choice, an experienced LDAP programmer
might not even understand what it is doing!
</p>
        <p>
Additionally, the SDK docs for the directories themselves (AD and ADAM) are still
mostly written for the unmanaged VB or C++ programmers with little attention to the
managed code devs (although ADAM is much better about that).  However, you won't
find a single S.DS.P sample in any of that.  It is as if the API didn't exist. 
The managed code docs are also spread out between the .NET SDK and the Directory Services
SDK, so it is hard to know where to look to get help.
</p>
        <p>
There are two things missing here.  
</p>
        <ul>
          <li>
The S.DS.P docs are just embarassing and must be improved.  I'll give it some
more time.  
</li>
          <li>
The overall DS API documentation lacks strategy and makes the platform harder to consume
than it needs to be.  Sure, that helps drive sales of our book, but trust me, we
didn't write it to make money.</li>
        </ul>
        <p>
On the bright side, there is a lot of low hanging fruit available here. :)
</p>
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=668538b6-547f-4b96-af85-4f9d3a6baad2" />
      </body>
      <title>Eric is doing some S.DS.P programming</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,668538b6-547f-4b96-af85-4f9d3a6baad2.aspx</guid>
      <link>http://www.joekaplan.net/EricIsDoingSomeSDSPProgramming.aspx</link>
      <pubDate>Sat, 28 Oct 2006 05:13:16 GMT</pubDate>
      <description>&lt;p&gt;
One of my favorite softies, &lt;a href="http://blogs.technet.com/efleis/default.aspx"&gt;Eric
Fleischman&lt;/a&gt;, is doing &lt;a href="http://blogs.technet.com/efleis/archive/2006/10/26/finding-the-lost-found-container-in-s-ds-p-or-anything-that-isn-t-adsi-really.aspx"&gt;some
S.DS.P programming&lt;/a&gt; these days.&amp;nbsp; He demonstrates a useful technique, which
is how to do WKGUID searches to find well-known objects in AD or ADAM.&amp;nbsp; For those
not familiar with this, AD and ADAM have a set of "well-known" objects that the directory
always contains and applications may need to find to do reasonable things.&amp;nbsp; However,
the names of these objects may be internationalized, so it may not be possible to
find them by name across different implementations of the directory.&amp;nbsp; By referencing
them by the "well-known" GUID, a published value, you can always find them.
&lt;/p&gt;
&lt;p&gt;
One of the things we didn't do in our book was provide matching S.DS.P samples for
most of the techniques.&amp;nbsp; In fact, we barely covered it at all.&amp;nbsp; I still
have some regrets about this, although I also think we probably did the right thing.&amp;nbsp;
If the book had been 800 pages due to all the extra samples, that would have been
tough.&amp;nbsp; I do think there might be a place to supplement the material with online
materials at some point.&amp;nbsp; I'm not sure another print tome dedicated to the subject
would ever sell very well as the audience is probably limited and likely needs the
material less than than the audience we originally wrote the book for (I could be
wrong about this).&amp;nbsp; The internal debate continues...
&lt;/p&gt;
&lt;p&gt;
One of the things that Eric does hit on is the somewhat sad state of affairs of the
MSDN&amp;nbsp;DS API documentation.&amp;nbsp; The S.DS.P docs are especially heinous, as they
include almost NO samples and even have some stuff documented as wrong or misleading.&amp;nbsp;
For example, the documentation for the &lt;a href="http://blogs.technet.com/efleis/archive/2006/10/26/finding-the-lost-found-container-in-s-ds-p-or-anything-that-isn-t-adsi-really.aspx"&gt;DistinguishedName&lt;/a&gt; property
on the SearchRequest class doesn't even succeed in identifying that as the search
BASE of the search, instead calling it the "object to search for".&amp;nbsp; If it wasn't
for the fact that there is no other obvious choice, an experienced LDAP programmer
might not even understand what it is doing!
&lt;/p&gt;
&lt;p&gt;
Additionally, the SDK docs for the directories themselves (AD and ADAM) are still
mostly written for the unmanaged VB or C++ programmers with little attention to the
managed code devs (although ADAM is much better about that).&amp;nbsp; However, you won't
find a single S.DS.P sample in any of that.&amp;nbsp; It is as if the API didn't exist.&amp;nbsp;
The managed code docs are also spread out between the .NET SDK and the Directory Services
SDK, so it is hard to know where to look to get help.
&lt;/p&gt;
&lt;p&gt;
There are two things missing here.&amp;nbsp; 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The S.DS.P docs are just embarassing and must be improved.&amp;nbsp; I'll give it some
more time.&amp;nbsp; 
&lt;/li&gt;
&lt;li&gt;
The overall DS API documentation lacks strategy and makes the platform harder to consume
than it needs to be.&amp;nbsp; Sure, that helps drive sales of our book, but trust me,&amp;nbsp;we
didn't write it to make money.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
On the bright side, there is a lot of low hanging fruit available here. :)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=668538b6-547f-4b96-af85-4f9d3a6baad2" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,668538b6-547f-4b96-af85-4f9d3a6baad2.aspx</comments>
      <category>LDAP</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=d6bdf538-f0d1-4dbf-a9de-2302f6e68eb2</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,d6bdf538-f0d1-4dbf-a9de-2302f6e68eb2.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,d6bdf538-f0d1-4dbf-a9de-2302f6e68eb2.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=d6bdf538-f0d1-4dbf-a9de-2302f6e68eb2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Ok, so I've bought a new house, sold my old one, moved and have my life returning
to its typical state of order.  Baseball season ended tonight (congrats to the
Cards; I couldn't really get into it though), I have broadband and the weather is
starting to lend itself towards staying inside.  As such, it is time to start
blogging again and getting back into some technology.  
</p>
        <p>
For anyone who may have ever subscribed to this humble sign post and was not impressed
by the quantity of content forthcoming, I will now try to ratchet things back up.
</p>
        <p>
On my mind these days are still ADFS and Identity Federation in general (which we
are getting close to deploying at the mothership now), directory programming (as usual),
crypto and application-level authorization approaches (a la AzMan).  Let's see
what I can come up with.  :)
</p>
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=d6bdf538-f0d1-4dbf-a9de-2302f6e68eb2" />
      </body>
      <title>Getting back to it...</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,d6bdf538-f0d1-4dbf-a9de-2302f6e68eb2.aspx</guid>
      <link>http://www.joekaplan.net/GettingBackToIt.aspx</link>
      <pubDate>Sat, 28 Oct 2006 04:41:47 GMT</pubDate>
      <description>&lt;p&gt;
Ok, so I've bought a new house, sold my old one, moved and have my life returning
to its typical state of order.&amp;nbsp; Baseball season ended tonight (congrats to the
Cards; I couldn't really get into it though), I have broadband and the weather is
starting to lend itself towards staying inside.&amp;nbsp; As such, it is time to start
blogging again and getting back into some technology.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
For anyone who may have ever subscribed to this humble sign post and was not impressed
by the quantity of content forthcoming, I will now try to ratchet things back up.
&lt;/p&gt;
&lt;p&gt;
On my mind these days are still ADFS and Identity Federation in general (which we
are getting close to deploying at the mothership now), directory programming (as usual),
crypto and application-level authorization approaches (a la AzMan).&amp;nbsp; Let's see
what I can come up with.&amp;nbsp; :)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=d6bdf538-f0d1-4dbf-a9de-2302f6e68eb2" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,d6bdf538-f0d1-4dbf-a9de-2302f6e68eb2.aspx</comments>
      <category>General</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=c92e0d51-90b9-4b6f-9d97-9dd9fb7d7530</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,c92e0d51-90b9-4b6f-9d97-9dd9fb7d7530.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,c92e0d51-90b9-4b6f-9d97-9dd9fb7d7530.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=c92e0d51-90b9-4b6f-9d97-9dd9fb7d7530</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
An interesting thread popped up on the newsgroups today involving a poster who was
trying to prevent his LDAP client from doing client certificate authentication by
using a feature in the LDAP API that allows you to supply a callback function that
handles the client certificate selection process.  Unfortunately, the poster
found what he thought was a memory leak.
</p>
        <p>
The intrepid <a href="http://www.joeware.net">Joe Richards</a> jumped in and with
the help of the trusty MVP source access, his brain and a helpful MS employee, <a href="http://blog.joeware.net/2006/10/06/656/">found
the bug, reported it and created a workaround</a>.  Nice job!  Joe goes
into excruciating detail, so I won't add anything to his investigation.
</p>
        <p>
The interesting thing for .NET developers is that this issue potentially affects users
of System.DirectoryServices.Protocols (SDS.P).  SDS.P provides a direct wrapper
around the leaking callback function in the LDAP API with the QueryClientCertificateDelegate
method.  I did a a little Reflectoring and it looks to me like the workaround
Joe suggested isn't implemented in SDS.P.
</p>
        <p>
Thus, if you are using this callback, you could have the same memory leak.  The
thing that really sucks is that Joe's workaround requires that you have a pointer
in the allocated structure so that you can pass it into the appropriate deallocation
function.  However, the .NET function prototype conveniently marshals all the
data for you into an array of byte arrays, so you no longer have the pointer. 
As such, you can't implement the workaround in .NET at all.
</p>
        <p>
As such, in order to deal with this situation, you probably need to the QFE that Joe
mentions (or perhaps a patch to SDS.P, although to my knowledge no such thing exists).  
</p>
        <p>
I discussed this particular function's friend, VerifyServerCertificateCallback, in
my <a href="http://www.joekaplan.net/Example1ForSDSPSSLCertificates.aspx">posting</a> describing
how to check a domain controller certificate expiration date on its SSL/LDAP cert. 
The QueryClientCertificateCallback is useful when you need to pick a specific client
cert, or when you want to prevent the automatic Schannel layer for looking for a client
certificate at all (which is what the original poster was doing).  The client
certificate negotiation can be really slow and isn't really helpful in a lot of circumstances
if you don't want to try to use client certificate authentication to bind with (which
is another black hole of MS LDAP client documentation void best saved for another
post).  
</p>
        <img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=c92e0d51-90b9-4b6f-9d97-9dd9fb7d7530" />
      </body>
      <title>Joe Richards find LDAP Client API Bug that Affects S.DS.Protocols</title>
      <guid isPermaLink="false">http://www.joekaplan.net/PermaLink,guid,c92e0d51-90b9-4b6f-9d97-9dd9fb7d7530.aspx</guid>
      <link>http://www.joekaplan.net/JoeRichardsFindLDAPClientAPIBugThatAffectsSDSProtocols.aspx</link>
      <pubDate>Sat, 07 Oct 2006 02:35:50 GMT</pubDate>
      <description>&lt;p&gt;
An interesting thread popped up on the newsgroups today involving a poster who was
trying to prevent his LDAP client from doing client certificate authentication by
using a feature in the LDAP API that allows you to supply a callback function that
handles the client certificate selection process.&amp;nbsp; Unfortunately, the poster
found what he thought was a memory leak.
&lt;/p&gt;
&lt;p&gt;
The intrepid &lt;a href="http://www.joeware.net"&gt;Joe Richards&lt;/a&gt; jumped in and with
the help of the trusty MVP source access, his brain and a helpful MS employee, &lt;a href="http://blog.joeware.net/2006/10/06/656/"&gt;found
the bug, reported it and created a workaround&lt;/a&gt;.&amp;nbsp; Nice job!&amp;nbsp; Joe goes
into excruciating detail, so I won't add anything to his investigation.
&lt;/p&gt;
&lt;p&gt;
The interesting thing for .NET developers is that this issue potentially affects users
of System.DirectoryServices.Protocols (SDS.P).&amp;nbsp; SDS.P provides a direct wrapper
around the leaking callback function in the LDAP API with the QueryClientCertificateDelegate
method.&amp;nbsp; I did a a little Reflectoring and it looks to me like the workaround
Joe suggested isn't implemented in SDS.P.
&lt;/p&gt;
&lt;p&gt;
Thus, if you are using this callback, you could have the same memory leak.&amp;nbsp; The
thing that really sucks is that Joe's workaround requires that you have a pointer
in the allocated structure so that you can pass it into the appropriate deallocation
function.&amp;nbsp; However, the .NET function prototype conveniently marshals all the
data for you into an array of byte arrays, so you no longer have the pointer.&amp;nbsp;
As such, you can't implement the workaround in .NET at all.
&lt;/p&gt;
&lt;p&gt;
As such, in order to deal with this situation, you probably need to the QFE that Joe
mentions (or perhaps a patch to SDS.P, although to my knowledge no such thing exists).&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
I discussed this particular function's friend, VerifyServerCertificateCallback, in
my &lt;a href="http://www.joekaplan.net/Example1ForSDSPSSLCertificates.aspx"&gt;posting&lt;/a&gt; describing
how to check a domain controller certificate expiration date on its SSL/LDAP cert.&amp;nbsp;
The QueryClientCertificateCallback is useful when you need to pick a specific client
cert, or when you want to prevent the automatic Schannel layer for looking for a client
certificate at all (which is what the original poster was doing).&amp;nbsp; The client
certificate negotiation can be really slow and isn't really helpful in a lot of circumstances
if you don't want to try to use client certificate authentication to bind with (which
is another black hole of MS LDAP client documentation void best saved for another
post).&amp;nbsp; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.joekaplan.net/aggbug.ashx?id=c92e0d51-90b9-4b6f-9d97-9dd9fb7d7530" /&gt;</description>
      <comments>http://www.joekaplan.net/CommentView,guid,c92e0d51-90b9-4b6f-9d97-9dd9fb7d7530.aspx</comments>
      <category>LDAP</category>
    </item>
    <item>
      <trackback:ping>http://www.joekaplan.net/Trackback.aspx?guid=637a1db3-198d-4215-ae8f-6b0ee4b3c671</trackback:ping>
      <pingback:server>http://www.joekaplan.net/pingback.aspx</pingback:server>
      <pingback:target>http://www.joekaplan.net/PermaLink,guid,637a1db3-198d-4215-ae8f-6b0ee4b3c671.aspx</pingback:target>
      <dc:creator>Joe Kaplan</dc:creator>
      <wfw:comment>http://www.joekaplan.net/CommentView,guid,637a1db3-198d-4215-ae8f-6b0ee4b3c671.aspx</wfw:comment>
      <wfw:commentRss>http://www.joekaplan.net/SyndicationService.asmx/GetEntryCommentsRss?guid=637a1db3-198d-4215-ae8f-6b0ee4b3c671</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
An interesting thread on LDAP and authentication came up again today on activedir.org. 
In the conversation, I had suggested that it would be a good feature if AD and ADAM
had a setting somewhere that could be enabled that would prevent LDAP simple bind
from working if the network channel was not secured (via SSL).  The problem with
simple bind (for those not in the know) is that the user's credentials are passed
over the network in plaintext, which is potentially a huge security risk (depending
on the network).  It is actually even worse (by just a little) that HTTP basic
authentication, as the credentials aren't even base64 encoded.
</p>
        <p>
Eric Fleischman then pointed out that ADAM actually already has such a switch. 
Tomek blogged about it <a href="http://blogs.dirteam.com/blogs/tomek/archive/2006/09/24/Disable-simple-bind-without-SSL-on-ADAM.aspx">here</a>,
so I'll let him cover the details on how to enable this.