﻿<?xml version="1.0" encoding="UTF-8"?>
<!--RSS generated by Microsoft SharePoint Foundation RSS Generator on 5/20/2012 6:08:50 AM -->
<?xml-stylesheet type="text/xsl" href="/_layouts/RssXslt.aspx?List=d3ff5463-71f3-45a2-a8c8-eaf94df8e5a1" version="1.0"?>
<rss version="2.0">
  <channel>
    <title>SharePoint 2010 Blog: Posts</title>
    <link>http://balki:82/Lists/Posts/AllPosts.aspx</link>
    <description>RSS feed for the Posts list.</description>
    <lastBuildDate>Sun, 20 May 2012 10:08:50 GMT</lastBuildDate>
    <generator>Microsoft SharePoint Foundation RSS Generator</generator>
    <ttl>60</ttl>
    <language>en-US</language>
    <image>
      <title>SharePoint 2010 Blog: Posts</title>
      <url>http://balki:82/_layouts/images/siteIcon.png</url>
      <link>http://balki:82/Lists/Posts/AllPosts.aspx</link>
    </image>
    <item>
      <title>Mixing it up w/ Mixed SSL &amp; SP 2010</title>
      <link>http://balki:82/Lists/Posts/ViewPost.aspx?ID=5</link>
      <description><![CDATA[<div><b>Body:</b> <div class="ExternalClass32C9DDD48EA04A40866D427D609887B0"><p><strong class="ms-rteFontSize-3">​UPDATE</strong></p>
<p><strong class="ms-rteFontSize-3"></strong>Chris Coulson wrote a detailed post on <a href="http://blogs.visigo.com/chriscoulson/mixed-http-and-https-content-with-sharepoint-2010/">his blog</a> about this topic (with very easy to follow steps).  Very nice work Chris!  <br /></p>
<p><br /></p>
<p><br /></p>
<p><br /> <style>
.ExternalClass32C9DDD48EA04A40866D427D609887B0 P.MsoNormal
{margin:0in 0in 0pt;font-family:'Calibri', 'sans-serif';font-size:11pt;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 LI.MsoNormal
{margin:0in 0in 0pt;font-family:'Calibri', 'sans-serif';font-size:11pt;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 DIV.MsoNormal
{margin:0in 0in 0pt;font-family:'Calibri', 'sans-serif';font-size:11pt;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 A:link
{color:blue;text-decoration:underline;text-underline:single;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 SPAN.MsoHyperlink
{color:blue;text-decoration:underline;text-underline:single;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 A:visited
{color:purple;text-decoration:underline;text-underline:single;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 SPAN.MsoHyperlinkFollowed
{color:purple;text-decoration:underline;text-underline:single;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 P.MsoListParagraph
{margin:0in 0in 0pt 0.5in;font-family:'Calibri', 'sans-serif';font-size:11pt;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 LI.MsoListParagraph
{margin:0in 0in 0pt 0.5in;font-family:'Calibri', 'sans-serif';font-size:11pt;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 DIV.MsoListParagraph
{margin:0in 0in 0pt 0.5in;font-family:'Calibri', 'sans-serif';font-size:11pt;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 .MsoChpDefault
{font-size:10pt;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 DIV.WordSection1
{page:WordSection1;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 OL
{margin-bottom:0in;}
.ExternalClass32C9DDD48EA04A40866D427D609887B0 UL
{margin-bottom:0in;}
</style></p>
<div>(My original post below...) <br /><br /></div>
<p class="MsoNormal"><span>Very good reading if you want to learn more on the inner workings of federated authentication models w/ claims &amp; sp2010:<br /><a href="http://msdn.microsoft.com/en-us/library/ee517293.aspx">http://msdn.microsoft.com/en-us/library/ee517293.aspx</a> </span></p>
<div> </div>
<p class="MsoNormal"><span> </span><span> </span> </p>
<p class="MsoNormal"><span>So after much digging with  <a href="http://getfirebug.com/">firebug</a> + the <a href="https://addons.mozilla.org/en-US/firefox/addon/60/">Firefox webdev extension</a> to inspect my http sessions, I discovered 2 funny things about the cookie SharePoint is setting</span></p>
<div> </div>
<p class="MsoNormal"><span> </span> </p>
<p class="MsoListParagraph" style="text-indent:-0.25in"><span><span>1)<span style="font:7pt &quot;times new roman&quot;">      </span></span></span><span>It ignores most of the settings we put in our &lt;forms tag and uses its own (see below)</span></p>
<div> </div>
<p class="MsoListParagraph" style="text-indent:-0.25in"><span><span>2)<span style="font:7pt &quot;times new roman&quot;">      </span></span></span><span>No matter what attributes I set, the cookie was being written as a secure cookie, which prevented it from being transmitted via non-secure http requests</span></p>
<div> </div>
<p class="MsoNormal"><span> </span></p>
<div> </div>
<p class="MsoNormal" style="text-align:left"><span> <img class="ms-rtePosition-3 ms-rteImage-1" alt="ssl_securecookie.png" src="/PublishingImages/ssl_securecookie.png" style="margin:5px" /><br /></span></p>
<div> </div>
<p class="MsoNormal" style="margin-bottom:12pt"><span>I inspected the web.config some more and discovered that SharePoint is using a custom cookie handler to read/write cookies:  </span></p>
<p class="ms-rteElement-P"><span>        &lt;cookieHandler mode=&quot;Custom&quot; path=&quot;/&quot;&gt;</span></p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P"><span>&lt;customCookieHandler type=&quot;Microsoft.SharePoint.IdentityModel.SPChunkedCookieHandler, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c&quot; /&gt;</span></p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P"><span>        &lt;/cookieHandler&gt;</span></p>
<div> </div>
<p class="MsoNormal"><span> </span></p>
<div>  </div>
<p class="MsoNormal"><b><span style="font-size:16pt">Enter Reflector</span><span>: <br /><br /></span></b><span>once I opened up this class in reflector and traced the life of a cookie during an authentication session, it turned out that there was a hardcoded reference to the https protocol in the WriteCore method – this was trumping any of the manual settings we were trying to add in the web.config</span></p>
<div>  </div>
<p class="MsoNormal"> </p>
<div> </div>
<p class="MsoNormal"><span><img width="939" height="474" class="ms-rteImage-1" alt="ssl_reflector.png" src="/PublishingImages/ssl_reflector.png" style="margin:5px;width:871px;height:405px" /></span></p>
<p class="MsoNormal"><span> </span></p>
<div> </div>
<p class="MsoNormal"><b><span style="font-size:16pt">The Fix:</span></b></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span>Fortunately a custom cookie handler class is not that complex, so I created a new MSNGNChunkedCookieHandler class and updated the web.config entry</span></p>
<p class="MsoNormal"><span>        </span></p>
<p class="ms-rteElement-P"><span>&lt;cookieHandler mode=&quot;Custom&quot; path=&quot;/&quot; requireSsl=&quot;false&quot; &gt; <br />          &lt;!-- &lt;customCookieHandler type=&quot;Microsoft.SharePoint.IdentityModel.SPChunkedCookieHandler, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c&quot; /&gt; --&gt;<br />                &lt;customCookieHandler type=&quot;MSNGN.Utility.MSNGNChunkedCookieHandler, </span><span><span><span>MSNGN.Utility</span></span></span><span>, Version=1.0.0.0, Culture=neutral, PublicKeyToken=38c82c65bfb6cec0&quot; /&gt;<br />        &lt;/cookieHandler&gt;</span></p>
<p class="ms-rteElement-P"> </p>
<div> </div>
<p class="MsoNormal"><span>This class invokes its base methods for the most part, I just slightly modified the WriteCore event w/ logic that removes the https hard coded reference.  </span></p>
<div> </div>
<p class="MsoNormal"><span> </span></p>
<p class="ms-rteElement-P">=== BEGIN CODE BLOCK ===</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">using System;</p>
<p class="ms-rteElement-P">using System.Web;</p>
<p class="ms-rteElement-P">using System.Collections.Generic;</p>
<p class="ms-rteElement-P">using System.Linq;</p>
<p class="ms-rteElement-P">using System.Text;</p>
<p class="ms-rteElement-P">using Microsoft.SharePoint.IdentityModel;</p>
<p class="ms-rteElement-P">using Microsoft.IdentityModel.Web;</p>
<p class="ms-rteElement-P">using Microsoft.SharePoint.Administration;</p>
<p class="ms-rteElement-P">using Microsoft.SharePoint.Administration.Claims;</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">namespace MSNGN.Utility</p>
<p class="ms-rteElement-P">{</p>
<p class="ms-rteElement-P">    /// &lt;summary&gt;</p>
<p class="ms-rteElement-P">    /// This is an override of the Microsoft.SharePoint.IdentityModel.SPChunkedCookieHandler class</p>
<p class="ms-rteElement-P">    /// with the WriteCore method extended to support both Secure &amp; Non-Secure cookies</p>
<p class="ms-rteElement-P">    /// &lt;/summary&gt;</p>
<p class="ms-rteElement-P">    public class MSNGNChunkedCookieHandler : Microsoft.SharePoint.IdentityModel.SPChunkedCookieHandler</p>
<p class="ms-rteElement-P">    {</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">        private ChunkedCookieHandler m_CookieHandler;</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">        public MSNGNChunkedCookieHandler() : base()</p>
<p class="ms-rteElement-P">        {</p>
<p class="ms-rteElement-P">            this.m_CookieHandler = new ChunkedCookieHandler();</p>
<p class="ms-rteElement-P">            this.m_CookieHandler.Path = &quot;/&quot;;</p>
<p class="ms-rteElement-P">        }</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">        public MSNGNChunkedCookieHandler(int chunkSize) : base(chunkSize)</p>
<p class="ms-rteElement-P">        {</p>
<p class="ms-rteElement-P">            this.m_CookieHandler = new ChunkedCookieHandler(chunkSize);</p>
<p class="ms-rteElement-P">            this.m_CookieHandler.Path = &quot;/&quot;;</p>
<p class="ms-rteElement-P">        }</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">        protected override void DeleteCore(string name, string path, string domain, HttpContext context)</p>
<p class="ms-rteElement-P">        {</p>
<p class="ms-rteElement-P">            base.DeleteCore(name, path, domain, context);</p>
<p class="ms-rteElement-P">        }</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">        protected override byte[] ReadCore(string name, HttpContext context)</p>
<p class="ms-rteElement-P">        {</p>
<p class="ms-rteElement-P">            return base.ReadCore(name, context);</p>
<p class="ms-rteElement-P">        }</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">        /// &lt;summary&gt;</p>
<p class="ms-rteElement-P">        /// Override of the WrieCore method to remove hard coded secure cookie flag</p>
<p class="ms-rteElement-P">        /// which is required to support both http &amp; non-http sessions</p>
<p class="ms-rteElement-P">        /// &lt;/summary&gt;</p>
<p class="ms-rteElement-P">        protected override void WriteCore(byte[] value, string name, string path, string domain, DateTime expirationTime, bool secure, bool httpOnly, System.Web.HttpContext context)</p>
<p class="ms-rteElement-P">        {</p>
<p class="ms-rteElement-P">            //override the secure cookie setting</p>
<p class="ms-rteElement-P">            //to enable both https &amp; non https cookie sessions</p>
<p class="ms-rteElement-P">            secure = false;</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">            if (context == null)</p>
<p class="ms-rteElement-P">            {</p>
<p class="ms-rteElement-P">                throw new ArgumentNullException(&quot;context&quot;);</p>
<p class="ms-rteElement-P">            }</p>
<p class="ms-rteElement-P">            if (context.Request == null)</p>
<p class="ms-rteElement-P">            {</p>
<p class="ms-rteElement-P">                throw new ArgumentException(null, &quot;context&quot;);</p>
<p class="ms-rteElement-P">            }</p>
<p class="ms-rteElement-P">            if (null == context.Request.Url)</p>
<p class="ms-rteElement-P">            {</p>
<p class="ms-rteElement-P">                throw new ArgumentException(null, &quot;context&quot;);</p>
<p class="ms-rteElement-P">            }</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">            //if (string.Equals(context.Request.Url.Scheme, &quot;https&quot;, StringComparison.OrdinalIgnoreCase))</p>
<p class="ms-rteElement-P">            //{</p>
<p class="ms-rteElement-P">            //    secure = true;</p>
<p class="ms-rteElement-P">            //}</p>
<p class="ms-rteElement-P">            //else</p>
<p class="ms-rteElement-P">            //{</p>
<p class="ms-rteElement-P">            //    secure = false;</p>
<p class="ms-rteElement-P">            //}</p>
<p class="ms-rteElement-P">            if (!string.Equals(path, &quot;/&quot;, StringComparison.OrdinalIgnoreCase))</p>
<p class="ms-rteElement-P">            {</p>
<p class="ms-rteElement-P">                path = &quot;/&quot;;</p>
<p class="ms-rteElement-P">            }</p>
<p class="ms-rteElement-P">            this.m_CookieHandler.Write(value, name, path, domain, expirationTime, secure, httpOnly, context);</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">        }</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">    }</p>
<p class="ms-rteElement-P">}</p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P"> </p>
<p class="ms-rteElement-P">=== END CODE BLOCK ===</p>
<div> </div>
<p class="MsoNormal"><span>I also threw together a quick “SSLTrafficCop” http module to route requests to either the secure or non-secure channel.  At the moment, the logic directs requests to the following paths to HTTPS, the other requests are routed through HTTP.  We can think about the best place to store these settings where they can be more configurable, but for now this will work for the remote authors.</span></p>
<div> </div>
<p class="MsoNormal"><span> </span></p>
<div> <span style="font-family:consolas;font-size:9.5pt"><span style="color:blue">public</span> <span style="color:blue">static</span> <span style="color:blue">string</span>[] SecurePaths =  <span style="color:blue">new</span> [] { <span>&quot;/_layouts/login/&quot;</span>, <span>&quot;/_layouts/userregistration/&quot;</span>};</span></div>
<div> </div>
<p class="MsoNormal"><span> </span> </p>
<p class="MsoNormal"><span>To install the traffic cop, simply add the following entry to our ever growing list of modules in the web.config.   This should only be installed on machines with valid SSL certs, so probably best to leave this setting off of the dev machines.</span></p>
<p class="MsoNormal"> </p>
<div> </div>
<p class="MsoNormal"><span> </span></p>
<span class="ms-rteStyle-Caption"></span><span class="ms-rteStyle-References"></span></div></div>
<div><b>Category:</b> <a onclick="OpenPopUpPage('http://balki:82/_layouts/listform.aspx?PageType=4&ListId={C7169AF4-7EA3-42DF-9BAF-49885CE759E6}&ID=7&RootFolder=*', RefreshPage); return false;" href="http://balki:82/_layouts/listform.aspx?PageType=4&ListId={C7169AF4-7EA3-42DF-9BAF-49885CE759E6}&ID=7&RootFolder=*">FBA</a></div>
<div><b>Published:</b> 8/8/2010 1:36 AM</div>
]]></description>
      <author>Tim Nugiel</author>
      <category>FBA</category>
      <pubDate>Sun, 08 Aug 2010 05:33:18 GMT</pubDate>
      <guid isPermaLink="true">http://balki:82/Lists/Posts/ViewPost.aspx?ID=5</guid>
    </item>
  </channel>
</rss>
