<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Tips, tricks and other animals</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/bradleycotier/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/bradleycotier/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 04:48:11 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>SAML 2.0 tokens and WIF – bridging the divide</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/saml-2-0-tokens-and-wif-bridging-the-divide</link>
      <pubDate>Sun, 28 Oct 2012 14:53:00 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2012/10/28/saml-2-0-tokens-and-wif-bridging-the-divide/</guid>
      <description><![CDATA[Background  We all know the following limitations about Windows Identity Foundation (WIF) and...]]></description>
      <content:encoded><![CDATA[<h2>Background</h2>  <p>We all know the following limitations about Windows Identity Foundation (WIF) and passive (browser) federation protocols, right?</p>  <ul>   <li>WIF does not support <a href="https://www.oasis-open.org/standards#samlv2.0">SAML2.0</a> protocol (SAML2P)</li>    <ul>     <li>There is a WIF extension out there to support SAML2P but it is a technology preview</li>   </ul>    <li>WIF does support SAML2.0 (SAML2) tokens</li>    <li><a href="https://docs.oasis-open.org/wsfed/federation/v1.2/os/ws-federation-1.2-spec-os.html">WS-Federation</a> conveys SAML1.1 tokens</li> </ul>  <p>Therefore, unless you use the WIF extension there is no way of getting a SAML2 token into a Relying Party (RP) application.</p>  <p>Well, did you know the following?</p>  <ul>   <li>WS-Federation responses convey <a href="https://schemas.xmlsoap.org/ws/2005/02/trust/">WS-Trust</a> RequestSecurityTokenResponse (RSTR) elements containing security tokens</li>    <li>The RSTR element is not tied into a particular token format</li>    <ul>     <li>i.e. – it is a &lt;xs:any&gt; element in the schema</li>   </ul> </ul>  <p>This means that it is perfectly valid for a WS-Federation response to convey a SAML2.0 token and it is only because WS-Federation existed before SAML2P that it became a de facto convention for WS-Federation to convey SAML1.1 tokens.</p>  <p>So, it IS possible to get a SAML2 token into a RP application as long as it is possible to get a SAML2 token into a WS-Federation response.</p>  <p>Here’s how.</p>  <h2>Methodology</h2>  <p>To achieve this I am using Active Directory Federation Services (<a href="https://technet.microsoft.com/en-us/library/adfs2(v=WS.10).aspx">ADFS 2.0</a>) as it is simple to integrate with WIF and it understands SAML2P, and therefore SAML2 tokens.</p>  <p>The setup is a Windows Server 2012 domain controller with the ADFS 2.1 role installed. All code was written using Visual Studio 2012 and .NET framework 4.5 although the same could be achieved with Windows Server 2008 R2, Visual Studio 2010 and .NET framework 4.0.</p>  <p>As discussed, this won’t work:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/1423.image_3F8F7244.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/1423.image_5F00_3F8F7244.png"><img title="image" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/4135.image_thumb_0383308F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/4135.image_5F00_thumb_5F00_0383308F.png" width="552" height="196" /></a></p>  <p>But this should:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/5228.image_4B813CAB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/5228.image_5F00_4B813CAB.png"><img title="image" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/3644.image_thumb_5368B940.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/3644.image_5F00_thumb_5F00_5368B940.png" width="733" height="162" /></a></p>  <p>The strategy is to place an intermediary RP-STS between RP and ADFS which performs protocol transition from SAML2P to WS-Federation.</p>  <p>To make things a little simpler, I have applied the following restrictions to the RP-STS:</p>  <ul>   <li>It is not a signing authority</li>    <ul>     <li>That is, it cannot create authoritative tokens itself but simply passes on tokens received from other providers</li>   </ul>    <li>It does not validate either the protocol wrapper or token itself</li>    <ul>     <li>This would involve a lot of extra code and the RP is going to do it anyway</li>      <li>The SAMLResponse wrapper element received from ADFS containing a SAML2 token is not digitally signed</li>      <ul>       <li>The SAML2P specification does allow for a digital signature though</li>     </ul>   </ul>    <li>The RP-STS only recognises messages transmitted using the <a href="https://www.oasis-open.org/standards#samlv2.0">SAML 2.0 HTTP redirect and POST bindings</a></li>    <ul>     <ul></ul>   </ul> </ul>  <p>The RP-STS itself is simply a ASP.NET HTTP module hosted in IIS. The first event in the ASP.NET pipeline, BeginRequest, is handled as there is nothing more for the module to do than parse tokens.</p>  <p>The flow of events is as follows:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/6763.image_69DB57C7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/6763.image_5F00_69DB57C7.png"><img title="image" style="border: 0px currentcolor; padding-top: 0px; padding-right: 0px; padding-left: 0px; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/5822.image_thumb_1BF28245.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/5822.image_5F00_thumb_5F00_1BF28245.png" width="386" height="618" /></a></p>  <p>The actual code is shown below:</p>  <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">   <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">namespace</span> RelyingPartySTS<br />{<br />    <span style="color: rgb(0, 0, 255);">using</span> System;<br />    <span style="color: rgb(0, 0, 255);">using</span> System.Configuration;<br />    <span style="color: rgb(0, 0, 255);">using</span> System.IdentityModel.Protocols.WSTrust;<br />    <span style="color: rgb(0, 0, 255);">using</span> System.IdentityModel.Services;<br />    <span style="color: rgb(0, 0, 255);">using</span> System.IdentityModel.Tokens;<br />    <span style="color: rgb(0, 0, 255);">using</span> System.IO;<br />    <span style="color: rgb(0, 0, 255);">using</span> System.Web;<br />    <span style="color: rgb(0, 0, 255);">using</span> System.Xml;<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> TranslatorModule : IHttpModule<br />    {<br />        <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">string</span> SamlRequestTemplate = <span style="color: rgb(0, 96, 128);">&quot;&lt;samlp:AuthnRequest ID=\&quot;id-{0}\&quot; Version=\&quot;2.0\&quot; IssueInstant=\&quot;{1}\&quot; Destination=\&quot;https://www.bradsts.com/adfs/ls/\&quot; Consent=\&quot;urn:oasis:names:tc:SAML:2.0:consent:unspecified\&quot; xmlns:samlp=\&quot;urn:oasis:names:tc:SAML:2.0:protocol\&quot;&gt;&lt;Issuer xmlns=\&quot;urn:oasis:names:tc:SAML:2.0:assertion\&quot;&gt;{2}&lt;/Issuer&gt;&lt;samlp:NameIDPolicy Format=\&quot;urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\&quot; AllowCreate=\&quot;true\&quot; /&gt;&lt;/samlp:AuthnRequest&gt;&quot;</span>;<br /><br />        <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">string</span> SamlHandlerContent = <span style="color: rgb(0, 96, 128);">&quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;Working...&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;form method='POST' name='hiddenform' action='{0}'&gt;&lt;input type='hidden' name='SAMLRequest' value='{1}' /&gt;&lt;noscript&gt;&lt;p&gt;Script is disabled. Click Submit to continue.&lt;/p&gt;&lt;input type='submit' value='Submit' /&gt;&lt;/noscript&gt;&lt;/form&gt;&lt;script language='javascript'&gt;window.setTimeout('document.forms[0].submit()', 0);&lt;/script&gt;&lt;/body&gt;&lt;/html&gt;&quot;</span>;<br /><br />        <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> Dispose()<br />        {<br />            <span style="color: rgb(0, 128, 0);">//clean-up code here.</span><br />        }<br /><br />        <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> Init(HttpApplication context)<br />        {<br />            context.BeginRequest += <span style="color: rgb(0, 0, 255);">new</span> EventHandler(OnBeginRequest);<br />        }<br /><br />        <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> OnBeginRequest(Object source, EventArgs e)<br />        {<br />            <span style="color: rgb(0, 0, 255);">try</span><br />            {<br />                WSFederationMessage mess = WSFederationMessage.CreateFromUri(HttpContext.Current.Request.Url);<br /><br />                <span style="color: rgb(0, 0, 255);">if</span> (mess <span style="color: rgb(0, 0, 255);">is</span> SignInRequestMessage)<br />                {<br />                    SignInRequestMessage messIn = mess <span style="color: rgb(0, 0, 255);">as</span> SignInRequestMessage;<br /><br />                    <span style="color: rgb(0, 128, 0);">// Convert the WS-Fed request into a SAML2 request</span><br />                    <span style="color: rgb(0, 0, 255);">string</span> parsedRequest = System.Web.HttpUtility.HtmlEncode(<br />                        System.Convert.ToBase64String(<br />                        System.Text.Encoding.UTF8.GetBytes(<br />                        <span style="color: rgb(0, 0, 255);">string</span>.Format(<br />                            SamlRequestTemplate, <br />                            Guid.NewGuid().ToString(), <br />                            DateTime.UtcNow.ToString(<span style="color: rgb(0, 96, 128);">&quot;yyyy-MM-ddTHH:MM:ss.fffZ&quot;</span>), <br />                            messIn.Realm))));<br /><br />                    <span style="color: rgb(0, 128, 0);">// Redirect the request to ADFS</span><br />                    <span style="color: rgb(0, 0, 255);">string</span> finalisedRedirectString = <span style="color: rgb(0, 0, 255);">string</span>.Format(<br />                        SamlHandlerContent,<br />                        ConfigurationManager.AppSettings[<span style="color: rgb(0, 96, 128);">&quot;stsUrl&quot;</span>],<br />                        parsedRequest);<br /><br />                    HttpContext.Current.Response.Write(finalisedRedirectString);<br />                    HttpContext.Current.ApplicationInstance.CompleteRequest();<br />                }<br />            }<br />            <span style="color: rgb(0, 0, 255);">catch</span> (WSFederationMessageException)<br />            {<br />                <span style="color: rgb(0, 128, 0);">// Parse the SAMLResponse</span><br />                <span style="color: rgb(0, 0, 255);">if</span> (HttpContext.Current.Request.Form.HasKeys())<br />                {<br />                    <span style="color: rgb(0, 0, 255);">if</span> (HttpContext.Current.Request.Form[<span style="color: rgb(0, 96, 128);">&quot;SAMLResponse&quot;</span>] != <span style="color: rgb(0, 0, 255);">null</span>)<br />                    {<br />                        <span style="color: rgb(0, 128, 0);">// Decode the response</span><br />                        <span style="color: rgb(0, 0, 255);">string</span> samlResponse = HttpContext.Current.Request.Form[<span style="color: rgb(0, 96, 128);">&quot;SAMLResponse&quot;</span>];<br />                        <span style="color: rgb(0, 0, 255);">string</span> responseDecoded = System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(System.Web.HttpUtility.HtmlDecode(samlResponse)));<br /><br />                        Saml2SecurityToken token = <span style="color: rgb(0, 0, 255);">null</span>;<br /><br />                        <span style="color: rgb(0, 128, 0);">// Pick out the token</span><br />                        <span style="color: rgb(0, 0, 255);">using</span> (StringReader sr = <span style="color: rgb(0, 0, 255);">new</span> StringReader(responseDecoded))<br />                        {<br />                            <span style="color: rgb(0, 0, 255);">using</span> (XmlReader reader = XmlReader.Create(sr))<br />                            {<br />                                reader.ReadToFollowing(<span style="color: rgb(0, 96, 128);">&quot;Assertion&quot;</span>, <span style="color: rgb(0, 96, 128);">&quot;urn:oasis:names:tc:SAML:2.0:assertion&quot;</span>);<br />                                <br />                                <span style="color: rgb(0, 128, 0);">// Deserialize the token so that data can be taken from it and plugged into the RSTR</span><br />                                SecurityTokenHandlerCollection coll = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();<br />                                token = (Saml2SecurityToken)coll.ReadToken(reader.ReadSubtree());<br />                            }<br />                        }<br /><br />                        <span style="color: rgb(0, 128, 0);">// Create a WS-Fed sign in response</span><br />                        RequestSecurityTokenResponse rstr = <span style="color: rgb(0, 0, 255);">new</span> RequestSecurityTokenResponse();<br />                        rstr.TokenType = <span style="color: rgb(0, 96, 128);">&quot;urn:oasis:names:tc:SAML:2.0:assertion&quot;</span>;<br />                        rstr.RequestType = <span style="color: rgb(0, 96, 128);">&quot;https://schemas.xmlsoap.org/ws/2005/02/trust/Issue&quot;</span>;<br />                        rstr.KeyType = <span style="color: rgb(0, 96, 128);">&quot;https://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey&quot;</span>;<br />                        rstr.Lifetime = <span style="color: rgb(0, 0, 255);">new</span> Lifetime(token.Assertion.IssueInstant, token.Assertion.Conditions.NotOnOrAfter);<br />                        rstr.AppliesTo = <span style="color: rgb(0, 0, 255);">new</span> EndpointReference(token.Assertion.Conditions.AudienceRestrictions[0].Audiences[0].OriginalString);<br />                        rstr.RequestedSecurityToken = <span style="color: rgb(0, 0, 255);">new</span> RequestedSecurityToken(token);<br />                        WSTrustFeb2005ResponseSerializer ser = <span style="color: rgb(0, 0, 255);">new</span> WSTrustFeb2005ResponseSerializer();<br />                        MemoryStream ms = <span style="color: rgb(0, 0, 255);">new</span> MemoryStream();<br /><br />                        SignInResponseMessage messOut = <span style="color: rgb(0, 0, 255);">null</span>;<br /><br />                        <span style="color: rgb(0, 0, 255);">using</span> (StreamReader sr = <span style="color: rgb(0, 0, 255);">new</span> StreamReader(ms))<br />                        {<br />                            <span style="color: rgb(0, 0, 255);">using</span> (XmlWriter writer = XmlWriter.Create(ms))<br />                            {<br />                                ser.WriteXml(rstr, writer, <span style="color: rgb(0, 0, 255);">new</span> WSTrustSerializationContext());<br />                            }<br /><br />                            ms.Position = 0;<br /><br />                            messOut = <span style="color: rgb(0, 0, 255);">new</span> SignInResponseMessage(<span style="color: rgb(0, 0, 255);">new</span> Uri(ConfigurationManager.AppSettings[<span style="color: rgb(0, 96, 128);">&quot;rpUrl&quot;</span>]), sr.ReadToEnd());<br />                        }                    <br /><br />                        <span style="color: rgb(0, 128, 0);">// Redirect the browser to RP</span><br />                        messOut.WriteFormPost();<br />                        HttpContext.Current.Response.Write(messOut.WriteFormPost());<br />                        HttpContext.Current.ApplicationInstance.CompleteRequest();<br />                    }<br />                }<br />            }<br />        }<br />    }<br />}<br /></pre>

  <br /></div>

<p>This ‘almost’ works in that the SAML2 token is successfully extracted from the ADFS response and plugged into a WS-Federation response which is forwarded to the RP website.</p>

<p>However, it turns out that WIF takes exception to the token! You will get the following error message:</p>

<p>“ID4154: A Saml2SecurityToken cannot be created from the Saml2Assertion because it contains a SubjectConfirmationData which specifies an InResponseTo value. Enforcement of this value is not supported by default. To customize SubjectConfirmationData processing, extend Saml2SecurityTokenHandler and override ValidateConfirmationData.”</p>

<p>If, as the error suggests, a custom SecurityTokenHandler implementation is created that derives from the default Saml2SecurityTokenHandler implementation, and the ValidateConfirmationData method is overridden, this error can be avoided.</p>

<p><strong><em>An aside:</em></strong></p>

<p>In fact, upon inspection of the SAML2 token, the InResponseTo attribute referred to above is actually inappropriate for the RP website as it contains the URL for the RP-STS website. However, as WIF appears to block tokens containing this attribute anyway, there can’t very well be much meaningful code beyond the error that would worry about it.</p>

<p>I believe that this inaccuracy in the URL could be circumvented by combining the RP and RP-STS websites together so that they exist under a common domain name. The conversion from WS-Federation request to SAMLRequest could take place in the OnRedirectingToIdentityProvider event handler and conversely, the conversion from ADFS SAMLResponse to WS-Federation response could take place in a HTTP module which fires <em>before </em>the default WIF pipeline takes over.</p>

<h2>Conclusion</h2>

<p>I have shown that it is possible to use relatively few lines of code to facilitate the transmission of SAML2 tokens into a standard WIF protected website by transitioning to/from WS-Federation to SAML2P federation protocols.</p>

<p>I believe that in the absence of proper SAML2P support in Windows Identity Foundation this approach, with a bit of work to bring the code up to production standards, is a viable one.</p>

<p>[BradleyCotier]</p>]]></content:encoded>
    </item>
    <item>
      <title>Access to an ASP.NET website via multiple authentications</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/access-to-an-asp-net-website-via-multiple-authentications</link>
      <pubDate>Tue, 23 Oct 2012 08:23:04 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2012/10/23/access-to-an-asp-net-website-via-multiple-authentications/</guid>
      <description><![CDATA[Background  Is it possible to secure a website using Windows Identity Foundation (WIF) without...]]></description>
      <content:encoded><![CDATA[<h1 class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">Background</h1>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">Is it possible to secure a website using Windows Identity Foundation (WIF) without interfering with an existing authentication method? e.g. – Could a website secured using an ASP.NET membership provider, with all the code and configuration that entails, be layered with additional code and configuration to allow a precursory authentication with a trusted Identity Provider (IdP). In a more extreme case, would it be possible to force a user to authenticate with a trusted IdP of choice before also forcing them to authenticate with another trusted IdP? In both cases surely there would be too much overlap such that one would interfere with the other, making the combination untenable.</p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">Well, before answering the question, why might you want to do this?</p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">A recent project was concerned with providing Windows Azure hosting capabilities for customer websites. The product enables creation of customisable boiler plate websites and automated deployment and management/monitoring of said websites into Azure. As all websites in Azure are publicly available (ok you would have to know the cloudapp.net URL) the customer had no opportunity to test the finished website before it was available to a public audience. Therefore, a specific functional requirement was for the production website to be up and running in ‘preview’ mode and for only the preview audience to have access to it; the preview audience being a limited number of website developers/stakeholders. Once the website passed muster, a switch could be flicked and the public audience would gain access.</p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">(It should be mentioned that securing the site by client ip address was untenable as the preview audience could range from tablet owners sitting in internet cafes to desktop based developers working either at home or in the office.)</p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">Instead, the customer exposes their corporate Active Directory to the internet using Active Directory Federation Services (ADFS 2.0) and so this was potentially an authoritative source for authenticating the preview audience. The problem was how to use this resource without fundamentally modifying the existing authentication mechanism for the website.</p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">Essentially:</p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">“I want authN method X in production but in preview I want authN method Y followed by authN method X”</p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">So, in the production configuration (i.e – authN method X only), the website may utilise an ASP.NET membership provider or perhaps federate with an external identity provider such as Live, Facebook etc. In fact it could employ <strong>any</strong> flavour of authentication/authorisation. An example is shown below where WIF is used to federate with Live, via the Azure Access Control Service (ACS):</p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/7713.image_7BE78864.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/7713.image_5F00_7BE78864.png"><img title="image" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/8877.image_thumb_411FDF8E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/8877.image_5F00_thumb_5F00_411FDF8E.png" width="796" height="574" /></a></p>  <p>In the preview configuration, there would be an additional authentication step so that the preview audience would have to log in with their corporate credentials against ADFS 2.0 and then <strong>also</strong> have to log in to Live, via ACS. An example is shown below:</p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/4130.image_319CCDBF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/4130.image_5F00_319CCDBF.png"><img title="image" style="border: 0px currentcolor; padding-top: 0px; padding-right: 0px; padding-left: 0px; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/7360.image_thumb_55094C57.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/7360.image_5F00_thumb_5F00_55094C57.png" width="806" height="443" /></a></p>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">In the methodology that follows I have used Visual Studio 2012, .NET4.5 (WIF is baked into .NET4.5 whereas previously it was a separate download), IIS8 and Windows Server 2012. However, the general methodology will also apply to Visual Studio 2010, .NET4, IIS7.5 and Windows Server 2008 R2.</p>  <h1 class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">Methodology</h1>  <p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">Ordinarily, WIF is enforced by two HTTP modules which are injected into the web.config file for the website (I have abbreviated the assembly names for formatting purposes):</p>  <div class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">   <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">     <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">system.webServer</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">modules</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;WSFederationAuthenticationModule&quot;</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;SessionAuthenticationModule&quot;</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">modules</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">system.webServer</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>

    <br /></div>
</div>

<p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">These modules implement event handlers that are raised in the ASP.NET pipeline for each HTTP request. Using the source code decompiler of your choice, we find that the earliest event handler for each module is the AuthenticateRequest event.</p>

<p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">To layer ADFS authentication on top of this I am going to implement a custom HTTP module and similarly handle the AuthenticateRequest event. Crucially though, the custom module is first in the module list so that it fires <strong>before </strong>the WIF modules:</p>

<div class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">
  <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">
    <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">system.webServer</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">modules</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;BouncerModule&quot;</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;RelyingParty.BouncerModule, RelyingParty&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;WSFederationAuthenticationModule&quot;</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;SessionAuthenticationModule&quot;</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">modules</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">system.webServer</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>

    <br /></div>
</div>

<p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">Apologies for the name ‘BouncerModule’. It just kind of stuck amongst the team and it does sort of act in the role of a nightclub doorman.</p>

<p class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">So, what are the important characteristics of the module?</p>

<div class="ExternalClass89E11C71AA8749C488CF6C23AC81FC3C">
  <ul>
    <li>It must enforce federation with an identity provider</li>

    <ul>
      <li>In this case the corporate ADFS</li>
    </ul>

    <li>It should make use of WIF classes as much as possible to avoid reinventing the wheel</li>

    <li>It must not interfere with the existing ASP.NET pipeline for the website</li>

    <ul>
      <li>None of the configuration contained within the web.config file for the website can be repurposed. e.g. - </li>

      <ul>
        <li>&lt;system.web&gt;/&lt;authorization&gt;</li>

        <li>&lt;system.web&gt;/&lt;authentication&gt;</li>
      </ul>

      <li>The module should not set anything in the HTTP context. CurrentPrincipal etc.</li>
    </ul>
  </ul>
</div>

<p>To achieve most of these aims I will make use of named WIF configuration.</p>

<p>What do I mean by named configuration?</p>

<p>For a standard WIF protected website in .NET 4.5 (in this case the website federates with Azure Access Control Service (ACS)), the configuration looks like the following:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">system.identityModel</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">identityConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />      <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">value</span><span style="color: rgb(0, 0, 255);">=&quot;urn:relyingpartyacs.com&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />      <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">trustedIssuers</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">thumbprint</span><span style="color: rgb(0, 0, 255);">=&quot;4AC4CB9A11C9EEDA95DA3B65295BD56F365E65FF&quot;</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;https://bradcot.accesscontrol.windows.net/&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />      <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">trustedIssuers</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">certificateValidation</span> <span style="color: rgb(255, 0, 0);">certificateValidationMode</span><span style="color: rgb(0, 0, 255);">=&quot;None&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">identityConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">system.identityModel</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">system.identityModel.services</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">federationConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">cookieHandler</span> <span style="color: rgb(255, 0, 0);">requireSsl</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">wsFederation</span> <span style="color: rgb(255, 0, 0);">passiveRedirectEnabled</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <span style="color: rgb(255, 0, 0);">issuer</span><span style="color: rgb(0, 0, 255);">=&quot;https://bradcot.accesscontrol.windows.net/v2/wsfederation&quot;</span> <span style="color: rgb(255, 0, 0);">realm</span><span style="color: rgb(0, 0, 255);">=&quot;urn:relyingpartyacs.com&quot;</span> <span style="color: rgb(255, 0, 0);">requireHttps</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">federationConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">system.identityModel.services</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>

  <br /></div>

<p>For this configuration, when the website is browsed, the user is asked to authenticate at Live, via Azure ACS, as is desired in production.</p>

<p>Below the configuration is extended to include sections that are explicitly named. A new &lt;identityConfiguration&gt; element named ‘adfs’ is added (the name chosen is not important) which in turn is referenced by a similarly named &lt;federationConfiguration&gt; element.</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">system.identityModel</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">identityConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />      <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">value</span><span style="color: rgb(0, 0, 255);">=&quot;urn:relyingpartyacs.com&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />      <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">trustedIssuers</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">thumbprint</span><span style="color: rgb(0, 0, 255);">=&quot;4AC4CB9A11C9EEDA95DA3B65295BD56F365E65FF&quot;</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;https://bradcot.accesscontrol.windows.net/&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />      <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">trustedIssuers</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">certificateValidation</span> <span style="color: rgb(255, 0, 0);">certificateValidationMode</span><span style="color: rgb(0, 0, 255);">=&quot;None&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">identityConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><strong>  <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">identityConfiguration</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;adfs&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />      <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">value</span><span style="color: rgb(0, 0, 255);">=&quot;urn:relyingpartyadfs.com&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />      <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">trustedIssuers</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">thumbprint</span><span style="color: rgb(0, 0, 255);">=&quot;416565b7d2193df7cc82de7981df59a600b7af67&quot;</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;https://www.bradsts.com/adfs/services/trust/&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />      <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">trustedIssuers</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">certificateValidation</span> <span style="color: rgb(255, 0, 0);">certificateValidationMode</span><span style="color: rgb(0, 0, 255);">=&quot;None&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">identityConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span></strong><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">system.identityModel</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">system.identityModel.services</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">federationConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">cookieHandler</span> <span style="color: rgb(255, 0, 0);">requireSsl</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">wsFederation</span> <span style="color: rgb(255, 0, 0);">passiveRedirectEnabled</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <span style="color: rgb(255, 0, 0);">issuer</span><span style="color: rgb(0, 0, 255);">=&quot;https://bradcot.accesscontrol.windows.net/v2/wsfederation&quot;</span> <span style="color: rgb(255, 0, 0);">realm</span><span style="color: rgb(0, 0, 255);">=&quot;urn:relyingpartyacs.com&quot;</span> <span style="color: rgb(255, 0, 0);">requireHttps</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">federationConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />  <strong><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">federationConfiguration</span> <span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">=&quot;adfs&quot;</span> <span style="color: rgb(255, 0, 0);">identityConfigurationName</span><span style="color: rgb(0, 0, 255);">=&quot;adfs&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">cookieHandler</span> <span style="color: rgb(255, 0, 0);">requireSsl</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">wsFederation</span> <span style="color: rgb(255, 0, 0);">passiveRedirectEnabled</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <span style="color: rgb(255, 0, 0);">issuer</span><span style="color: rgb(0, 0, 255);">=&quot;https://www.bradsts.com/adfs/ls/&quot;</span> <span style="color: rgb(255, 0, 0);">realm</span><span style="color: rgb(0, 0, 255);">=&quot;urn:relyingpartyadfs.com&quot;</span> <span style="color: rgb(255, 0, 0);">requireHttps</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />  <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">federationConfiguration</span><span style="color: rgb(0, 0, 255);">&gt;</span></strong><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">system.identityModel.services</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>

  <br /></div>

<p>The WIF pipeline will only use the unnamed sections. However, with the bouncer module in place, the named configuration can be used as follows:</p>

<p>&#160;</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/2642.image_612AC67E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/2642.image_5F00_612AC67E.png"><img title="image" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/5775.image_thumb_2A6D6B7A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/5775.image_5F00_thumb_5F00_2A6D6B7A.png" width="622" height="1254" /></a></p>

<p><strong>N.B. – I have not included the code but would be happy to discuss any aspect of it if you have specific questions.</strong></p>

<p>Some steps need a bit of explanation:</p>

<p>4 &amp; 12 – It is crucial that the session cookie created by the bouncer module has a different name to that used by the WIF pipeline, ‘FedAuth’. In this way the ADFS token that is contained within the cookie does not overlap with the ACS token.</p>

<p>6 – If the ADFS token passes validation there is nothing more to be done. End and allow the WIF pipeline to process the session cookie containing the ACS token. Otherwise, redirect the browser to ADFS for re-authentication.</p>

<p>11 – The reply address is stored within the ‘ru’ query string parameter of the redirect received from ADFS. The reply address is either the root of the website or a relative URI to a location within the website. If these checks are not performed it might be possible for a nefarious query string to cause the browser to be redirected to a malicious website.</p>

<h1>Conclusion</h1>

<p>In this article I have shown that it is possible to add an extra authentication step into a website, on top of the existing authentication method. In the example a website which, in production, would federate with Live via Azure ACS, was altered so that a precursory authentication against ADFS was mandated.</p>

<p>This was all achieved using named WIF configuration and a standalone ASP.NET HTTP module that very deliberately leaves no trace in the pipeline after execution is complete.</p>

<p>[BradleyCotier]</p>]]></content:encoded>
    </item>
    <item>
      <title>ADFS/C2WTS identity impersonation failure after an IIS reset</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/adfsc2wts-identity-impersonation-failure-after-an-iis-reset</link>
      <pubDate>Tue, 27 Mar 2012 14:24:46 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2012/03/27/adfsc2wts-identity-impersonation-failure-after-an-iis-reset/</guid>
      <description><![CDATA[My team recently encountered an issue at a Relying Party website where identity impersonation in...]]></description>
      <content:encoded><![CDATA[<p>My team recently encountered an issue at a Relying Party website where identity impersonation in combination with ADFS authentication and the Claims to Windows Token service (C2WTS) fails after an IIS reset is performed.</p>  <h1>Reproducing the problem</h1>  <p>The problem is easily reproduced using the following steps:</p>  <ul>   <li>Create an empty ASP.NET website and set up federation with ADFS</li>    <ul>     <li>Ensure that a UPN claim is emitted by ADFS</li>   </ul>    <li>Modify C:\Program Files\Windows Identity Foundation\v3.5\c2wtshost.exe.config to allow access to authenticated users </li> </ul>  <div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:dfb8e851-1217-48a1-8c44-4094cc015750" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">  &lt;</span><span style="color:#a31515">windowsTokenService</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">    &lt;!--</span></li> <li><span style="color:#008000">        By default no callers are allowed to use the Windows Identity Foundation Claims To NT Token Service.</span></li> <li style="background: #f3f3f3"><span style="color:#008000">        Add the identities you wish to allow below.</span></li> <li><span style="color:#008000">      </span><span style="color:#0000ff">--&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">allowedCallers</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">      &lt;</span><span style="color:#a31515">clear</span><span style="color:#0000ff">/&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">      &lt;!--</span><span style="color:#008000"> &lt;add value=&quot;NT AUTHORITY&#92;Network Service&quot; /&gt; </span><span style="color:#0000ff">--&gt; </span></li> <li><span style="color:#0000ff">      &lt;!--</span><span style="color:#008000"> &lt;add value=&quot;NT AUTHORITY&#92;Local Service&quot; /&gt; </span><span style="color:#0000ff">--&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">      &lt;!--</span><span style="color:#008000"> &lt;add value=&quot;NT AUTHORITY&#92;System&quot; /&gt; </span><span style="color:#0000ff">--&gt;</span></li> <li><span style="color:#0000ff">       &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">NT AUTHORITY&#92;Authenticated Users</span>&quot;<span style="color:#0000ff"> /&gt; </span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">    &lt;/</span><span style="color:#a31515">allowedCallers</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">  &lt;/</span><span style="color:#a31515">windowsTokenService</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>  <ul>   <li>Start the C2WTS service via start-run-services.msc</li>    <li>Modify the ASP.NET web.config file to enable identity impersonation</li> </ul>  <div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4195c3c0-fa31-4a94-80f2-eb0b39eaf20e" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">  &lt;</span><span style="color:#a31515">system.web</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">identity</span><span style="color:#0000ff"> </span><span style="color:#ff0000">impersonate</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">true</span>&quot;<span style="color:#0000ff">/&gt;</span></li> <li>    ...</li> </ol> </div> </div> </div>  <ul>   <li>Modify the ASP.NET web.config file to enable communication with the C2WTS service<span class="kwrd"></span></li> </ul>  <div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:05f090d7-ddc4-4ae1-92ae-8713a35cd3ed" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">  &lt;</span><span style="color:#a31515">microsoft.identityModel</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">service</span><span style="color:#0000ff">&gt;</span></li> <li>      ...</li> <li style="background: #f3f3f3"><span style="color:#0000ff">      &lt;</span><span style="color:#a31515">securityTokenHandlers</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">        &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">          &lt;</span><span style="color:#a31515">samlSecurityTokenRequirement</span><span style="color:#0000ff"> </span><span style="color:#ff0000">mapToWindows</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">true</span>&quot;<span style="color:#0000ff"> </span><span style="color:#ff0000">useWindowsTokenService</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">true</span>&quot;<span style="color:#0000ff"> /&gt;</span></li> <li><span style="color:#0000ff">        &lt;/</span><span style="color:#a31515">add</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">      &lt;/</span><span style="color:#a31515">securityTokenHandlers</span><span style="color:#0000ff">&gt;</span></li> <li>      ...</li> <li style="background: #f3f3f3"><span style="color:#0000ff">    &lt;/</span><span style="color:#a31515">service</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">  &lt;/</span><span style="color:#a31515">microsoft.identityModel</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>  <ul>   <li>Log in via ADFS</li>    <li>Perform an IIS reset</li>    <li>Refresh the page</li> </ul>  <p>The following error will occur:</p>  <p><strong>Either a required impersonation level was not provided, or the provided impersonation level is invalid. (Exception from HRESULT: 0x80070542)</strong></p>  <p>This error is fairly catastrophic as the entire app pool is compromised until it is recycled. i.e. – it is not the currently logged in user that no longer has access, <strong><em>it is all users!</em></strong></p>  <h1>The solution</h1>  <p>As stated previously, recycling the app pool resolves the issue but this is not a satisfactory solution.</p>  <p>To understand the solution it is necessary to go under the covers of Windows Identity Foundation and look at the innards of the Microsoft.IdentityModel.Tokens.Saml11.SAML11SecurityTokenHandler class.</p>  <p>Within the ValidateToken method the following code is executed:</p>  <div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:290b3a2f-bd20-4ee3-bf47-b600772c9b1f" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">if</span> (<span style="color:#0000ff">this</span>._samlSecurityTokenRequirement.MapToWindows)</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#2b91af">WindowsClaimsIdentity</span> identity2 = <span style="color:#2b91af">WindowsClaimsIdentity</span>.CreateFromUpn(<span style="color:#0000ff">this</span>.FindUpn(claimsIdentity), <span style="color:#a31515">&quot;Federation&quot;</span>, <span style="color:#0000ff">this</span>._samlSecurityTokenRequirement.UseWindowsTokenService, <span style="color:#0000ff">base</span>.Configuration.IssuerNameRegistry.GetWindowsIssuerName());</li> <li style="background: #f3f3f3">    identity2.Claims.CopyRange(claimsIdentity.Claims);</li> <li>    claimsIdentity = identity2;</li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div>  <p>As you can see, the code is conditional on the mapToWindows and useWindowsTokenService flags present in the microsoft.identityModel configuration section. This means that if both flags are true, the C2WTS service will be called every time the handler is invoked.</p>  <p>The problem though is that this handler is only invoked once when the SAML assertion from ADFS is first presented to the ASP.NET website. Every subsequent page hit instead invokes the Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler class which deserialises the claims collection held within a cookie. This handler does not, in the out of the box implementation, call the C2WTS service and so, after an IIS reset, even though the user still has access to the website based upon the cookie contents, all impersonation detail is lost and so the error occurs.</p>  <p>Some investigation of the SessionSecurityTokenHandler class reveals that it also uses a flag called useWindowsTokenService but it is false in the default implementation.</p>  <p>The solution is to remove the default SessionSecurityTokenHandler implementation and add in a new one where the useWindowsTokenService flag is set to true, as shown below:</p>  <div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0fd66544-935d-4244-bbe4-f2d9c073c235" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">  &lt;</span><span style="color:#a31515">microsoft.identityModel</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">service</span><span style="color:#0000ff">&gt;</span></li> <li>      ...</li> <li style="background: #f3f3f3"><span style="color:#0000ff">      &lt;</span><span style="color:#a31515">securityTokenHandlers</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">        &lt;</span><span style="color:#a31515">remove</span><span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>&quot;<span style="color:#0000ff"> /&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">        &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">          &lt;</span><span style="color:#a31515">sessionTokenRequirement</span><span style="color:#0000ff"> </span><span style="color:#ff0000">useWindowsTokenService</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">true</span>&quot;<span style="color:#0000ff">/&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">        &lt;/</span><span style="color:#a31515">add</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">        &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">          &lt;</span><span style="color:#a31515">samlSecurityTokenRequirement</span><span style="color:#0000ff"> </span><span style="color:#ff0000">mapToWindows</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">true</span>&quot;<span style="color:#0000ff"> </span><span style="color:#ff0000">useWindowsTokenService</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">true</span>&quot;<span style="color:#0000ff"> /&gt;</span></li> <li><span style="color:#0000ff">        &lt;/</span><span style="color:#a31515">add</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">      &lt;/</span><span style="color:#a31515">securityTokenHandlers</span><span style="color:#0000ff">&gt;</span></li> <li>      ...</li> <li style="background: #f3f3f3"><span style="color:#0000ff">    &lt;/</span><span style="color:#a31515">service</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">  &lt;/</span><span style="color:#a31515">microsoft.identityModel</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>  <p>The logged in session will now survive an IIS reset.</p>  <p>Hope this helps.</p>  <p>Brad</p>]]></content:encoded>
    </item>
    <item>
      <title>Claims to Windows Token Service keeps entering disabled state</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/claims-to-windows-token-service-keeps-entering-disabled-state</link>
      <pubDate>Fri, 24 Feb 2012 07:35:51 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2012/02/24/claims-to-windows-token-service-keeps-entering-disabled-state/</guid>
      <description><![CDATA[On a recent project I was tasked with securing an ASP.NET MVC site using ADFS. There was also a...]]></description>
      <content:encoded><![CDATA[<p>On a recent project I was tasked with securing an ASP.NET MVC site using ADFS. There was also a requirement to flow the end-user identity down through the various tiers, necessitating the use of Kerberos Constrained Delegation (KCD). In order to achieve KCD, the SAML assertion returned from ADFS must first be converted to a WindowsIdentity instance, using the Claims to Windows Token Service (C2WTS).</p>  <p>This worked fine but I kept seeing an intermittent error in the MVC site stating:</p>  <p>“The pipe endpoint 'net.pipe://localhost/s4u/022694f3-9fbd-422b-b4b2-312e25dae2a2' could not be found on your local machine.”</p>  <p>I tracked this down to the C2WTS service which was shutting down, with the following informational message written to the System event log:</p>  <p>“The Claims to Windows Token Service service entered the stopped state.”</p>  <p>and:</p>  <p>“The start type of the Claims to Windows Token Service service was changed from auto start to disabled.”</p>  <p>Note, there were no obviously related error messages, just these two statements.</p>  <p>I looked around the event logs and found this for the same timestamp:</p>  <p>“The SharePoint Health Analyzer found and fixed the following problem: One or more services have started or stopped unexpectedly.”</p>  <p>Sorry, I probably hadn’t mentioned until now that SharePoint 2010 was installed <img style="style" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/0412.wlEmoticon-smile_5DA52D44.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/0412.wlEmoticon_2D00_smile_5F00_5DA52D44.png" /> … anyway, it appeared that SharePoint was ‘fixing’ a problem for me. This kept me on the path of thinking that there was something wrong with the C2WTS service itself.</p>  <p>However, it transpired that SharePoint was in fact disabling the service because SharePoint configuration dictated that the service be stopped. When monitoring showed this not to be the case (because I re-enabled it), SharePoint would shut the service down again!</p>  <p>Therefore, the ‘Central Administration – Services on Server’ page within SharePoint that describes the state of services that SharePoint is dependent on <strong>not only describes the current state of the service but also the state that SharePoint would like it to be in.</strong></p>  <p>I therefore changed the expected state of the C2WTS service to started within SharePoint, and SharePoint duly started it up.</p>  <p>Finally, there was one more curveball thrown at me. When SharePoint started the service it also modified the C2WTS configuration file so that ONLY users of the WSS_WPG group could use it. As the MVC site in question was entirely separate from SharePoint, the C2WTS call still failed.</p>  <p>I therefore had to modify the C2WTS configuration file located at ‘C:\Program Files\Windows Identity Foundation\v3.5\c2wtshost.exe.config’ so that the <span class="kwrd">&lt;</span><span class="html">allowedCallers</span><span class="kwrd">&gt;</span> element went from:</p>  <pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">allowedCallers</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">clear</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">value</span><span class="kwrd">=&quot;WSS_WPG&quot;</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">allowedCallers</span><span class="kwrd">&gt;</span></pre>


<p>to:</p>

<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">allowedCallers</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">clear</span> <span class="kwrd">/&gt;</span>
    <span class="rem">&lt;!--&lt;add value=&quot;NT AUTHORITY\Network Service&quot; /&gt; </span>
<span class="rem">    &lt;add value=&quot;NT AUTHORITY\Local Service&quot; /&gt; </span>
<span class="rem">    &lt;add value=&quot;NT AUTHORITY\System&quot; /&gt;--&gt;</span> 
    <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">value</span><span class="kwrd">=&quot;NT AUTHORITY\Authenticated Users&quot;</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">allowedCallers</span><span class="kwrd">&gt;</span></pre>

<p>Hope this helps.</p>

<p>Brad</p>

<pre class="csharpcode"><span class="kwrd"><font color="#000000" face="Calibri"></font></span></pre>
]]></content:encoded>
    </item>
    <item>
      <title>Write a custom security token and handler in Windows Identity Foundation</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/write-a-custom-security-token-and-handler-in-windows-identity-foundation</link>
      <pubDate>Wed, 14 Dec 2011 07:23:31 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2011/12/14/write-a-custom-security-token-and-handler-in-windows-identity-foundation/</guid>
      <description><![CDATA[In this article I will demonstrate how to write a token handler for a custom token in Windows...]]></description>
      <content:encoded><![CDATA[<p>In this article I will demonstrate how to write a token handler for a custom token in Windows Identity Foundation (WIF). The likely circumstances for requiring a new token type are:</p>  <ul>   <li>The token type is pre-existing and needs to be federated</li>    <li>The new token type is an extension to a token type already supported by WIF</li>  </ul>  <p>However, the purpose of this article is to demonstrate one of the extensibility points of WIF and so the reasons for creating a new token type are not so important.</p>  <p>Before continuing I should point out that I am not creating a new wire protocol for conveying tokens but instead using an existing wire protocol (WS-Federation) to pass a new token type. WS-Federation is well suited to this because it is a means of conveying WS-Trust tokens using browser redirects. In turn, WS-Trust is essentially a container for …. well, any token type you like and that is why we can create a new token type without risk of breaking any standards.</p>  <p>I am going to take a trial and error approach to this so that you can see some of the common pitfalls. I will simply fire a new token, wrapped within a <a href="https://www.oasis-open.org/specs/index.php#wstrustv1.3">WS-Trust 1.3</a> envelope and conveyed by the <a href="https://www.oasis-open.org/specs/index.php#wsfedv1.2">WS-Federation Passive Requestor Profile</a>, as a sign-in response message to the Relying Party (RP) application. Then, I will fix the RP application by reacting to the errors that occur. Using this methodology you may get a fuller understanding of how to implement a new token handler and token.</p>  <p>First I need an STS to send a custom token to the RP. To do this I have captured a sign in response using <a href="https://www.httpwatch.com/">Http Watch</a> (a really good and easy to use HTTP sniffer), changed the token within the&#160; WS-Federation wresult parameter, and hardcoded it as the STS response; this was achieved using a ASP.NET website with a HttpHandler implementation.</p>  <p>The custom token to be consumed by the RP looks like the following:</p>  <div id="codeSnippetWrapper">   <div id="codeSnippetWrapper">     <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">m:MyCustomToken</span> <br />    <span style="color: rgb(255, 0, 0);">xmlns:m</span><span style="color: rgb(0, 0, 255);">=&quot;urn:mycustomtoken&quot;</span> <br />    <span style="color: rgb(255, 0, 0);">m:Id</span><span style="color: rgb(0, 0, 255);">=&quot;D416881A-130B-4AFF-8091-F412D7440E39&quot;</span> <br />    <span style="color: rgb(255, 0, 0);">m:Issuer</span><span style="color: rgb(0, 0, 255);">=&quot;urn:mycustomtokenhandlersts&quot;</span> <br />    <span style="color: rgb(255, 0, 0);">m:Audience</span><span style="color: rgb(0, 0, 255);">=&quot;https://mycustomtokenhandlerwebsite/&quot;</span> <br />    <span style="color: rgb(255, 0, 0);">m:ValidFrom</span><span style="color: rgb(0, 0, 255);">=&quot;2011-01-01&quot;</span> <br />    <span style="color: rgb(255, 0, 0);">m:ValidTo</span><span style="color: rgb(0, 0, 255);">=&quot;2099-12-31&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">m:Claim</span> <span style="color: rgb(255, 0, 0);">Name</span><span style="color: rgb(0, 0, 255);">=&quot;GivenName&quot;</span> <span style="color: rgb(255, 0, 0);">Namespace</span><span style="color: rgb(0, 0, 255);">=&quot;urn:givenname&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span>John<span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">m:Claim</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">m:Claim</span> <span style="color: rgb(255, 0, 0);">Name</span><span style="color: rgb(0, 0, 255);">=&quot;Surname&quot;</span> <span style="color: rgb(255, 0, 0);">Namespace</span><span style="color: rgb(0, 0, 255);">=&quot;urn:surname&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span>Doe<span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">m:Claim</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">m:Claim</span> <span style="color: rgb(255, 0, 0);">Name</span><span style="color: rgb(0, 0, 255);">=&quot;Role&quot;</span> <span style="color: rgb(255, 0, 0);">Namespace</span><span style="color: rgb(0, 0, 255);">=&quot;urn:role&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span>Manager<span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">m:Claim</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Signature</span> <span style="color: rgb(255, 0, 0);">xmlns</span><span style="color: rgb(0, 0, 255);">=&quot;https://www.w3.org/2000/09/xmldsig#&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">SignedInfo</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">CanonicalizationMethod</span> <span style="color: rgb(255, 0, 0);">Algorithm</span><span style="color: rgb(0, 0, 255);">=&quot;https://www.w3.org/2001/10/xml-exc-c14n#&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">SignatureMethod</span> <span style="color: rgb(255, 0, 0);">Algorithm</span><span style="color: rgb(0, 0, 255);">=&quot;https://www.w3.org/2000/09/xmldsig#rsa-sha1&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Reference</span> <span style="color: rgb(255, 0, 0);">URI</span><span style="color: rgb(0, 0, 255);">=&quot;&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />                <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Transforms</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />                    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Transform</span> <span style="color: rgb(255, 0, 0);">Algorithm</span><span style="color: rgb(0, 0, 255);">=&quot;https://www.w3.org/2000/09/xmldsig#enveloped-signature&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />                    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">Transform</span> <span style="color: rgb(255, 0, 0);">Algorithm</span><span style="color: rgb(0, 0, 255);">=&quot;https://www.w3.org/2001/10/xml-exc-c14n#&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />                <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">Transforms</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />                <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">DigestMethod</span> <span style="color: rgb(255, 0, 0);">Algorithm</span><span style="color: rgb(0, 0, 255);">=&quot;https://www.w3.org/2000/09/xmldsig#sha1&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />                <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">DigestValue</span><span style="color: rgb(0, 0, 255);">&gt;</span>gK8K+94DbXsVHxE8X3ulh45WcEM=<span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">DigestValue</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">Reference</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">SignedInfo</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">SignatureValue</span><span style="color: rgb(0, 0, 255);">&gt;</span>… removed for brevity …<span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">SignatureValue</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">KeyInfo</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">X509Data</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />                <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">X509Certificate</span><span style="color: rgb(0, 0, 255);">&gt;</span>… removed for brevity …<span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">X509Certificate</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">X509Data</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">KeyInfo</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">Signature</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">m:MyCustomToken</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>
  </div>

  <br />It contains many of the characteristics of common token types:</div>

<ul>
  <li>Id – a unique identifier for the token (can be used to detect replay attacks)</li>

  <li>Namespace – the namespace for the token</li>

  <li>Issuer – the entity that issued the token to the RP</li>

  <li>ValidFrom/ValidTo – the validity period of the token</li>

  <li>Audience – the entity that the token is intended for</li>

  <li>Claims – a set of authoritative statements about the identity described by the token</li>

  <li>Digital signature – ensures that the message cannot be tampered with and also enforces the authoritative nature of the message</li>
</ul>

<p>and the &lt;microsoft.identityModel&gt; configuration section of the RP config file currently has no awareness of the new token type:</p>

<div id="codeSnippetWrapper">
  <div id="codeSnippetWrapper">
    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">microsoft.identityModel</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">service</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">value</span><span style="color: rgb(0, 0, 255);">=&quot;https://mycustomtokenhandlerwebsite/&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">federatedAuthentication</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">wsFederation</span> <br />                <span style="color: rgb(255, 0, 0);">passiveRedirectEnabled</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <br />                <span style="color: rgb(255, 0, 0);">issuer</span><span style="color: rgb(0, 0, 255);">=&quot;https://localhost:29460/MyCustomTokenHandlerSTS/STSHandler.ashx&quot;</span> <br />                <span style="color: rgb(255, 0, 0);">realm</span><span style="color: rgb(0, 0, 255);">=&quot;https://mcthw&quot;</span> <br />                <span style="color: rgb(255, 0, 0);">requireHttps</span><span style="color: rgb(0, 0, 255);">=&quot;false&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">cookieHandler</span> <span style="color: rgb(255, 0, 0);">requireSsl</span><span style="color: rgb(0, 0, 255);">=&quot;false&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">federatedAuthentication</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">trustedIssuers</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">service</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">microsoft.identityModel</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>

    <br />OK, by browsing to the RP home page the browser is automatically redirected to the STS and the custom token is returned to the RP:</div>
</div>

<div>&#160;</div>

<div>Error!</div>

<div>&#160;</div>

<p><i><strong>“ID4014: A SecurityTokenHandler is not registered to read security token ('MyCustomToken', 'urn:mycustomtoken')”</strong></i></p>

<p>This seems reasonable as I have not yet made any effort to recognise the token. I therefore need the bare bones of a custom SecurityTokenHandler implementation:</p>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">using</span> System;<br /><span style="color: rgb(0, 0, 255);">using</span> Microsoft.IdentityModel.Tokens;<br /><br /><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br /><span style="color: rgb(0, 128, 0);">/// Summary description for MyCustomTokenHandler</span><br /><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> MyCustomTokenHandler : SecurityTokenHandler<br />{<br />    <span style="color: rgb(0, 0, 255);">public</span> MyCustomTokenHandler()<br />    {<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">string</span>[] GetTokenTypeIdentifiers()<br />    {<br />        <span style="color: rgb(0, 0, 255);">throw</span> <span style="color: rgb(0, 0, 255);">new</span> NotImplementedException();<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> Type TokenType<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">throw</span> <span style="color: rgb(0, 0, 255);">new</span> NotImplementedException(); }<br />    }<br />}</pre>

  <br />I also need a custom System.IdentityModel.Tokens.SecurityToken implementation representing the token type to be handled:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">using</span> System;<br /><span style="color: rgb(0, 0, 255);">using</span> System.IdentityModel.Tokens;<br /><br /><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br /><span style="color: rgb(0, 128, 0);">/// Summary description for MyCustomToken</span><br /><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> MyCustomToken : SecurityToken<br />{<br />    <span style="color: rgb(0, 0, 255);">public</span> MyCustomToken()<br />    {<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">string</span> Id<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">throw</span> <span style="color: rgb(0, 0, 255);">new</span> NotImplementedException(); }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> ReadOnlyCollection&lt;SecurityKey&gt; SecurityKeys<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">throw</span> <span style="color: rgb(0, 0, 255);">new</span> NotImplementedException(); }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> DateTime ValidFrom<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">throw</span> <span style="color: rgb(0, 0, 255);">new</span> NotImplementedException(); }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> DateTime ValidTo<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">throw</span> <span style="color: rgb(0, 0, 255);">new</span> NotImplementedException(); }<br />    }<br />}</pre>

  <br />Finally, I need to reference the handler in the RP config file by adding in a &lt;securityTokenHandlers&gt; element:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">securityTokenHandlers</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;MyCustomTokenHandler&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">securityTokenHandlers</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>

  <br />Browse to the RP again … Error!</div>

<div>&#160;</div>

<div><strong>“The method or operation is not implemented”</strong></div>

<div>&#160;</div>

<div>This occurs because I need to implement the handlers GetTokenTypeIdentifiers method to return the namespace of the new token, and also the TokenType property to return the tokens type:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <div id="codeSnippetWrapper">
    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">string</span>[] GetTokenTypeIdentifiers()<br />{<br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> <span style="color: rgb(0, 0, 255);">string</span>[] { <span style="color: rgb(0, 96, 128);">&quot;urn:mycustomtoken&quot;</span> };<br />}<br /><br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> Type TokenType<br />{<br />    get { <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">typeof</span>(MyCustomToken); }<br />}</pre>
  </div>

  <br />Browse to the RP again … Error!</div>

<div>&#160;</div>

<div><i><strong>“ID4014: A SecurityTokenHandler is not registered to read security token ('MyCustomToken', 'urn:mycustomtoken')”</strong></i></div>

<div><em>&#160;</em></div>

<div>This is a bit strange as I have implemented all of the methods mandated by the base class. After a quick peek into the WIF source I found the following:</div>

<div><em>&#160;</em></div>

<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">virtual</span> <span style="color: rgb(0, 0, 255);">bool</span> CanReadToken(XmlReader reader)<br />{<br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;<br />}</pre>

<div><em>&#160;</em></div>

<div id="codeSnippetWrapper">By default all security token handler implementations are excluded as possible candidates for parsing the token! I therefore need to override this method and perform some checks on the incoming token to make sure that my code genuinely can read the token:</div>

<div></div>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">bool</span> CanReadToken(XmlReader reader)<br />{<br />    <span style="color: rgb(0, 0, 255);">if</span> (reader.LocalName.Equals(<span style="color: rgb(0, 96, 128);">&quot;MyCustomToken&quot;</span>) &amp;&amp;<br />        reader.NamespaceURI.Equals(<span style="color: rgb(0, 96, 128);">&quot;urn:mycustomtoken&quot;</span>))<br />    {<br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;<br />}</pre>

  <br />Browse to the RP again … Error!</div>

<div>&#160;</div>

<div><strong><em>“ID4008: 'SecurityTokenHandler' does not provide an implementation for 'ReadToken'”</em></strong></div>

<div><em>&#160;</em></div>

<div>This seems self explanatory as I have indicated that I can read the token but have provided no code to do so. I need a SecurityToken implementation but the SecurityToken base class only offers a few read-only properties. It therefore seems that I must do most of the work myself. To achieve this I have created a internal representation of the token:</div>

<div><em></em>&#160;</div>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">using</span> System;<br /><span style="color: rgb(0, 0, 255);">using</span> System.Collections.Generic;<br /><span style="color: rgb(0, 0, 255);">using</span> Microsoft.IdentityModel.Claims;<br /><br /><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br /><span style="color: rgb(0, 128, 0);">/// Summary description for MyCustomTokenInternal</span><br /><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> MyCustomTokenInternal<br />{<br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">string</span> Id<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> DateTime ValidFrom<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> DateTime ValidTo<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">string</span> Audience<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">string</span> Issuer<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> IEnumerable&lt;Claim&gt; Claims<br />    {<br />        get;<br />        set;<br />    }<br />}</pre>

  <br />I have then used the internal token type to populate an instance of MyCustomToken in the ReadToken implementation of MyCustomTokenHandler:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <div id="codeSnippetWrapper">
    <div id="codeSnippetWrapper">
      <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> SecurityToken ReadToken(XmlReader reader)<br />{<br />    <span style="color: rgb(0, 128, 0);">// Check token signature using EnvelopedSignatureReader (more performant but more complex to use)</span><br />    <span style="color: rgb(0, 128, 0);">// or SignedXml (easier to use but less performant)</span><br /><br />    MyCustomToken token = <span style="color: rgb(0, 0, 255);">new</span> MyCustomToken(<br />        <span style="color: rgb(0, 0, 255);">new</span> MyCustomTokenInternal()<br />        {<br />            Id = reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;Id&quot;</span>, TokenNamespace),<br />            ValidFrom = XmlConvert.ToDateTime(reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;ValidFrom&quot;</span>, TokenNamespace)),<br />            ValidTo = XmlConvert.ToDateTime(reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;ValidTo&quot;</span>, TokenNamespace)),<br />            Audience = reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;Audience&quot;</span>, TokenNamespace),<br />            Issuer = reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;Issuer&quot;</span>, TokenNamespace),<br />            Claims = from el <span style="color: rgb(0, 0, 255);">in</span> XElement.Load(reader).Elements(XName.Get(<span style="color: rgb(0, 96, 128);">&quot;Claim&quot;</span>, TokenNamespace)) select <span style="color: rgb(0, 0, 255);">new</span> Claim(el.Attribute(<span style="color: rgb(0, 96, 128);">&quot;Namespace&quot;</span>).Value, el.Value)<br />        });<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> token;<br />}</pre>

      <br />Browse to the RP again … Error!</div>
  </div>
</div>

<div>&#160;</div>

<div><i><strong>“ID4011: A SecurityTokenHandler is not registered to validate token type 'MyCustomToken'”</strong></i></div>

<div>&#160;</div>

<div>Ok … as well as being able to read the token, the token handler also needs to be able to validate it. I therefore need to override the ValidateToken method and I am also going to preempt the possibility that I need to provide a ValidateToken implementation (as for CanReadToken/ReadToken):</div>

<div><em></em>&#160;</div>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">bool</span> CanValidateToken<br />{<br />    get<br />    {<br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;<br />    }<br />}<br /><br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> ClaimsIdentityCollection ValidateToken(SecurityToken token)<br />{<br />    ClaimsIdentityCollection idColl = <span style="color: rgb(0, 0, 255);">new</span> ClaimsIdentityCollection();<br /><br />    IClaimsIdentity id = <span style="color: rgb(0, 0, 255);">new</span> ClaimsIdentity((token <span style="color: rgb(0, 0, 255);">as</span> MyCustomToken).Claims);<br /><br />    idColl.Add(id);<br /><br />    <span style="color: rgb(0, 0, 255);">return</span> idColl;<br />}</pre>

  <br />Browse to the RP again … Success!</div>

<div>&#160;</div>

<div><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/4532.image_105422A5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/4532.image_5F00_105422A5.png"><img style="border: 0px currentcolor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/1817.image_thumb_162EC63E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/1817.image_5F00_thumb_5F00_162EC63E.png" width="444" height="149" /></a></div>

<div><em></em>&#160;</div>

<div>Finally, to prove that the token conditions are being honoured by WIF I have changed the ValidTo date to a time in the past. When I now attempt to browse to the RP I get the following error:</div>

<div>&#160;</div>

<div><i><strong>“Specified argument was out of the range of valid values. Parameter name: validFrom”</strong></i></div>

<div>&#160;</div>

<div>Which is slightly odd as it is the ValidTo date that is incorrect, but at least an error occurs.</div>

<div>&#160;</div>

<div>In conclusion, I have shown how it is possible to consume a custom token type in WIF using the SecurityToken and SecurityTokenHandler classes.</div>

<div>&#160;</div>

<div>Finally I have included the complete classes below for reference.</div>

<div>&#160;</div>

<div>Have fun!</div>

<div>&#160;</div>

<div>MyCustomTokenHandler:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">using</span> System;<br /><span style="color: rgb(0, 0, 255);">using</span> System.IdentityModel.Tokens;<br /><span style="color: rgb(0, 0, 255);">using</span> System.Linq;<br /><span style="color: rgb(0, 0, 255);">using</span> System.Xml;<br /><span style="color: rgb(0, 0, 255);">using</span> System.Xml.Linq;<br /><span style="color: rgb(0, 0, 255);">using</span> Microsoft.IdentityModel.Claims;<br /><span style="color: rgb(0, 0, 255);">using</span> Microsoft.IdentityModel.Tokens;<br /><br /><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br /><span style="color: rgb(0, 128, 0);">/// Summary description for MyCustomTokenHandler</span><br /><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> MyCustomTokenHandler : SecurityTokenHandler<br />{<br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">string</span> TokenNamespace = <span style="color: rgb(0, 96, 128);">&quot;urn:mycustomtoken&quot;</span>;<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> MyCustomTokenHandler()<br />    {<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">string</span>[] GetTokenTypeIdentifiers()<br />    {<br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> <span style="color: rgb(0, 0, 255);">string</span>[] { TokenNamespace };<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> Type TokenType<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">typeof</span>(MyCustomToken); }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">bool</span> CanReadKeyIdentifierClause(XmlReader reader)<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> (reader.LocalName.Equals(<span style="color: rgb(0, 96, 128);">&quot;X509Data&quot;</span>))<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;<br />        }<br /><br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">bool</span> CanReadToken(XmlReader reader)<br />    {<br />        <span style="color: rgb(0, 0, 255);">if</span> (reader.LocalName.Equals(<span style="color: rgb(0, 96, 128);">&quot;MyCustomToken&quot;</span>) &amp;&amp;<br />            reader.NamespaceURI.Equals(<span style="color: rgb(0, 96, 128);">&quot;urn:mycustomtoken&quot;</span>))<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;<br />        }<br /><br />        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> SecurityToken ReadToken(XmlReader reader)<br />    {<br />        <span style="color: rgb(0, 128, 0);">// Check token signature using EnvelopedSignatureReader (more performant but more complex to use)</span><br />        <span style="color: rgb(0, 128, 0);">// or SignedXml (easier to use but less performant)</span><br /><br />        MyCustomToken token = <span style="color: rgb(0, 0, 255);">new</span> MyCustomToken(<br />            <span style="color: rgb(0, 0, 255);">new</span> MyCustomTokenInternal()<br />            {<br />                Id = reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;Id&quot;</span>, TokenNamespace),<br />                ValidFrom = XmlConvert.ToDateTime(reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;ValidFrom&quot;</span>, TokenNamespace)),<br />                ValidTo = XmlConvert.ToDateTime(reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;ValidTo&quot;</span>, TokenNamespace)),<br />                Audience = reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;Audience&quot;</span>, TokenNamespace),<br />                Issuer = reader.GetAttribute(<span style="color: rgb(0, 96, 128);">&quot;Issuer&quot;</span>, TokenNamespace),<br />                Claims = from el <span style="color: rgb(0, 0, 255);">in</span> XElement.Load(reader).Elements(XName.Get(<span style="color: rgb(0, 96, 128);">&quot;Claim&quot;</span>, TokenNamespace)) select <span style="color: rgb(0, 0, 255);">new</span> Claim(el.Attribute(<span style="color: rgb(0, 96, 128);">&quot;Namespace&quot;</span>).Value, el.Value)<br />            });<br /><br />        <span style="color: rgb(0, 0, 255);">return</span> token;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">bool</span> CanValidateToken<br />    {<br />        get<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> ClaimsIdentityCollection ValidateToken(SecurityToken token)<br />    {<br />        ClaimsIdentityCollection idColl = <span style="color: rgb(0, 0, 255);">new</span> ClaimsIdentityCollection();<br /><br />        IClaimsIdentity id = <span style="color: rgb(0, 0, 255);">new</span> ClaimsIdentity((token <span style="color: rgb(0, 0, 255);">as</span> MyCustomToken).Claims);<br /><br />        idColl.Add(id);<br /><br />        <span style="color: rgb(0, 0, 255);">return</span> idColl;<br />    }<br />}</pre>

  <br />MyCustomToken:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">using</span> System;<br /><span style="color: rgb(0, 0, 255);">using</span> System.Collections.Generic;<br /><span style="color: rgb(0, 0, 255);">using</span> System.Collections.ObjectModel;<br /><span style="color: rgb(0, 0, 255);">using</span> System.IdentityModel.Tokens;<br /><span style="color: rgb(0, 0, 255);">using</span> Microsoft.IdentityModel.Claims;<br /><br /><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br /><span style="color: rgb(0, 128, 0);">/// Summary description for MyCustomToken</span><br /><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> MyCustomToken : SecurityToken<br />{<br />    <span style="color: rgb(0, 0, 255);">private</span> MyCustomTokenInternal tokenInt;<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> MyCustomToken(MyCustomTokenInternal tokenInt)<br />    {<br />        <span style="color: rgb(0, 0, 255);">this</span>.tokenInt = tokenInt;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">string</span> Id<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">this</span>.tokenInt.Id; }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> ReadOnlyCollection&lt;SecurityKey&gt; SecurityKeys<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">null</span>; }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> DateTime ValidFrom<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">this</span>.tokenInt.ValidFrom; }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> DateTime ValidTo<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">this</span>.tokenInt.ValidTo; }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> IEnumerable&lt;Claim&gt; Claims<br />    {<br />        get { <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">this</span>.tokenInt.Claims; }<br />    }<br />}</pre>

  <br />MyCustomTokenInternal:</div>

<div>&#160;</div>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">using</span> System;<br /><span style="color: rgb(0, 0, 255);">using</span> System.Collections.Generic;<br /><span style="color: rgb(0, 0, 255);">using</span> Microsoft.IdentityModel.Claims;<br /><br /><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br /><span style="color: rgb(0, 128, 0);">/// Summary description for MyCustomTokenInternal</span><br /><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> MyCustomTokenInternal<br />{<br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">string</span> Id<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> DateTime ValidFrom<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> DateTime ValidTo<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">string</span> Audience<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">string</span> Issuer<br />    {<br />        get;<br />        set;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> IEnumerable&lt;Claim&gt; Claims<br />    {<br />        get;<br />        set;<br />    }<br />}</pre>
</div>

<div>&#160;</div>

<div>RP web.config &lt;microsoft.identityModel&gt; config section:</div>

<div>&#160;</div>

<div>
  <div id="codeSnippetWrapper">
    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">microsoft.identityModel</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">service</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">value</span><span style="color: rgb(0, 0, 255);">=&quot;https://mycustomtokenhandlerwebsite/&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">audienceUris</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">federatedAuthentication</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">wsFederation</span> <br />                <span style="color: rgb(255, 0, 0);">passiveRedirectEnabled</span><span style="color: rgb(0, 0, 255);">=&quot;true&quot;</span> <br />                <span style="color: rgb(255, 0, 0);">issuer</span><span style="color: rgb(0, 0, 255);">=&quot;https://localhost:29460/MyCustomTokenHandlerSTS/STSHandler.ashx&quot;</span> <br />                <span style="color: rgb(255, 0, 0);">realm</span><span style="color: rgb(0, 0, 255);">=&quot;https://localhost:58724/MyCustomTokenHandlerWebsite/&quot;</span> <br />                <span style="color: rgb(255, 0, 0);">requireHttps</span><span style="color: rgb(0, 0, 255);">=&quot;false&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">cookieHandler</span> <span style="color: rgb(255, 0, 0);">requireSsl</span><span style="color: rgb(0, 0, 255);">=&quot;false&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">federatedAuthentication</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">trustedIssuers</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">issuerNameRegistry</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">securityTokenHandlers</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />            <span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">add</span> <span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;MyCustomTokenHandler&quot;</span> <span style="color: rgb(0, 0, 255);">/&gt;</span><br />        <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">securityTokenHandlers</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />    <span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">service</span><span style="color: rgb(0, 0, 255);">&gt;</span><br /><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">microsoft.identityModel</span><span style="color: rgb(0, 0, 255);">&gt;</span></pre>

    <br /></div>
 written by [bradleycotier]

  <br /></div>]]></content:encoded>
    </item>
    <item>
      <title>Handling optional claims with the ADFS Claims Rule Language</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/handling-optional-claims-with-the-adfs-claims-rule-language</link>
      <pubDate>Wed, 14 Dec 2011 07:18:50 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2011/12/14/handling-optional-claims-with-the-adfs-claims-rule-language/</guid>
      <description><![CDATA[It is a perfectly normal scenario for claims to be optional in a token. For example, a SAML...]]></description>
      <content:encoded><![CDATA[<p><font size="2">It is a perfectly normal scenario for claims to be optional in a token. For example, a SAML assertion may contain the mandatory claims:</font></p> <font size="2"> </font>  <ul><font size="2"> </font>    <li><font size="2">https://www.contoso.com/claims/givenname </font></li>    <li><font size="2">https://www.contoso.com/claims/surname</font></li> </ul> <font size="2"> </font>  <p><font size="2">and optionally the claim:</font></p> <font size="2"> </font>  <ul><font size="2"> </font>    <li><font size="2">https://www.contoso.com/claims/dateofbirth</font></li> </ul> <font size="2"> </font>  <p><font size="2">The </font><a href="https://technet.microsoft.com/en-us/library/dd807118(WS.10).aspx"><font size="2">ADFS Claims Rule Language</font></a><font size="2"> is designed to allow claims from incoming tokens to be used to query data stores for additional claims.</font></p> <font size="2"> </font>  <p><font size="2">At first glance it seems easy enough to construct claim rules that would execute for both the case where only the mandatory claims are present, and also the case where the optional claim is included.</font></p> <font size="2"> </font>  <p><font size="2">The first rule handles the case where all three claims are present:</font></p>    <div id="codeSnippetWrapper">   <pre style="margin: 0em; padding: 0px; width: 113.88%; height: 145px; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><p>c:[Type == &quot;https://www.contoso.com/claims/givenname&quot;]<br />&amp;&amp; c1:[Type == &quot;https://www.contoso.com/claims/surname&quot;]<br />&amp;&amp; c2:[Type == &quot;https://www.contoso.com/claims/dateofbirth&quot;]<br /><br />=<span style="color: rgb(0, 0, 255);">&gt;</span> ISSUE(store = &quot;Contoso Attribute Store&quot;, <br />TYPES = (&quot;https://www.contoso.com/claims/privatepersonalidentifier&quot;),<br />QUERY = &quot;Name={0},Surname={1},DateOfBirth={2}&quot;,</p><p>PARAM = c.Value, PARAM = c1.Value, PARAM = c2.Value);<br /></p></pre>
</div>

<p><font size="2">and the second rule handles the case where only the mandatory claims are present:</font></p>

<pre style="margin: 0em; padding: 0px; width: 113.88%; height: 130px; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><p>c:[Type == &quot;https://www.contoso.com/claims/givenname&quot;]<br />&amp;&amp; c1:[Type == &quot;https://www.contoso.com/claims/surname&quot;]<br /><br />=<span style="color: rgb(0, 0, 255);">&gt;</span> ISSUE(store = &quot;Contoso Attribute Store&quot;, <br />TYPES = (“https://www.contoso.com/claims/privatepersonalidentifier&quot;),<br />QUERY = &quot;Name={0},Surname={1}&quot;,</p><p>PARAM = c.Value, PARAM = c1.Value);<br /></p></pre>

<p><font size="2">So that the rules as viewed through the ADFS GUI look like the following:</font></p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/7888.image_2231F6A6.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/7888.image_5F00_2231F6A6.png"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/4572.image_thumb_131B17CC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/4572.image_5F00_thumb_5F00_131B17CC.png" width="543" height="590" /></a></p>

<p><font size="2">Unfortunately, this does not work as expected because of the principle that states:</font></p>
<font size="2"></font>

<p><font size="2">“All claim rules will fire whose query parameters are satisfied by the claims in the pipeline”</font></p>
<font size="2"></font>

<p><font size="2">This is fine for the mandatory claim case as only the second rule fires.</font></p>
<font size="2"></font>

<p><font size="2">However, if the optional claim is also present, both rules fire because the full set of input claims satisfy each set of search criteria. This is still ok if both rules return the same result because ADFS will condense any claims with identical namespace AND value into a single claim. But, it may be the case that the less specific rule, containing only the mandatory claims, will return multiple results (i.e - there are two people with the same name but different dates of birth). As previously stated, ADFS will condense any identical claims but there could still be additional results left over; clearly not ideal as it is possible, using the full set of input claims, to uniquely identify a single user.</font></p>
<font size="2"></font>

<p><font size="2">This problem has no solution without knowledge of the little documented '”NOT EXISTS” function, in conjunction with the better known ADD function.</font></p>
<font size="2"></font>

<p><font size="2">The trick is to create three rules.</font></p>
<font size="2"></font>

<p><font size="2">The first rule checks for the non-presence of the optional claim and adds a dummy claim into the claims pipeline, as follows:</font></p>
<font size="2"></font>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><font size="2" face="Segoe UI">NOT EXISTS([Type == &quot;https://www.contoso.com/claims/dateofbirth&quot;])<br />=<span style="color: rgb(0, 0, 255);">&gt;</span> ADD(Type = &quot;https://dummy&quot;, Value = &quot;dummy&quot;);</font></pre>
</div>
<font size="2"></font>

<p><font size="2">The second rule checks for the existence of the dummy rule and, if present, queries on the mandatory claims only:</font></p>
<font size="2"></font>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; height: 151px; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><p><font size="2" face="Segoe UI">c:[Type == &quot;https://www.contoso.com/claims/givenname&quot;]<br />&amp;&amp; c1:[Type == &quot;https://www.contoso.com/claims/surname”]<br />&amp;&amp; c2:[Type == &quot;https://dummy&quot;, Value == &quot;dummy&quot;]<br />=<span style="color: rgb(0, 0, 255);">&gt;</span> ISSUE(store = &quot;Contoso Attribute Store&quot;,</font></p><p><font size="2" face="Segoe UI">TYPES = (&quot;https://www.contoso.com/claims/privatepersonalidentifier&quot;),</font></p><p><font size="2" face="Segoe UI">QUERY = &quot;Forename={0},Surname={1}&quot;,</font></p><p><font size="2" face="Segoe UI">PARAM = c.Value, PARAM = c1.Value);<br /></font></p></pre>
</div>
<font size="2"></font>

<p><font size="2">The third rule simply queries on all three input claims:</font></p>
<font size="2"></font>

<div id="codeSnippetWrapper">
  <pre style="margin: 0em; padding: 0px; width: 100%; height: 132px; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);" id="codeSnippet"><p><font size="2" face="Segoe UI">c:[Type == &quot;https://www.contoso.com/claims/givenname&quot;]<br />&amp;&amp; c1:[Type == &quot;https://www.contoso.com/claims/surname&quot;]<br />&amp;&amp; c2:[Type == &quot;https://www.contoso.com/claims/dateofbirth&quot;]<br />=<span style="color: rgb(0, 0, 255);">&gt;</span> ISSUE(store = &quot;Contoso Attribute Store&quot;,<br />TYPES = (&quot;https://www.contoso.com/claims/privatepersonalidentifier&quot;),<br />QUERY = &quot;Forename={0},Surname={1},DateOfBirth={2}&quot;,</font></p><p><font size="2" face="Segoe UI">PARAM = c.Value, PARAM = c1.Value, PARAM = c2.Value);<br /></font></p></pre>
</div>
<font size="2"></font>

<p><font size="2">The combination works because the two rules that query the Contoso Attribute Store are orthogonal to each other and so only one will fire for a given set of input claims.</font></p>
<font size="2"></font>

<p><font size="2">Finally, it is worth noting that the ADD function in the first rule only adds a claim to the claims pipeline that will not be present in the resulting token.</font></p>

<p><font size="2">I hope you find this useful.</font></p>

<p>written by [bradleycotier]</p>]]></content:encoded>
    </item>
    <item>
      <title>Mutual authentication with a IIS hosted WCF data service installed in a workgroup environment</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/mutual-authentication-with-a-iis-hosted-wcf-data-service-installed-in-a-workgroup-environment</link>
      <pubDate>Wed, 14 Dec 2011 07:14:45 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2011/12/14/mutual-authentication-with-a-iis-hosted-wcf-data-service-installed-in-a-workgroup-environment/</guid>
      <description><![CDATA[This post covers the steps required to secure communication between a WCF client and a WCF data...]]></description>
      <content:encoded><![CDATA[<p><font size="2">This post covers the steps required to secure communication between a WCF client and a WCF data service using mutual certificate authentication.</font></p> <font size="2"></font>  <p><font size="2">The client/service topology is depicted below:</font></p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/1651.image17_4C7FDE04.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/1651.image17_5F00_4C7FDE04.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/5270.image17_thumb_525A819D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/5270.image17_5F00_thumb_5F00_525A819D.png" width="731" height="207" /></font></a></p>  <p><font size="2">Both the client and server run on a Windows Server 2008 R2 virtual machine with Windows SDK 7.1, Visual Studio 2010, SQL Server Express 2008 R2 and .NET framework 4.0.</font></p>  <h1><u>Mutual authentication explained</u></h1>  <p><font size="2">A detailed discussion of public key cryptography is outside the scope of this article. However, I highly recommend that you read more </font><a href="https://technet.microsoft.com/en-us/library/aa998077(EXCHG.65).aspx"><font size="2">here</font></a><font size="2"> to get a better understanding of the underlying principles, so that you can better understand the ‘How-To’ steps that follow.</font></p> <font size="2"></font>  <p><font size="2">In essence the client possesses a public key certificate (hereafter known as a client certificate) with associated private key. Similarly, the service has possession of another public key certificate (hereafter known as a service certificate) with associated private key. For a given pair of keys, either the public or private key can be used to encrypt data but ONLY the corresponding key can decrypt the data. The public key is available to the world at large but the private key MUST remain with the owner alone. In this way the owner is able to encrypt data using the private key and a party in receipt of encrypted data can decrypt it using the public key. The fact that the receiving party can successfully decrypt the data using the public key means that the data MUST have been encrypted by the corresponding private key and, as only the owner has access to the private key, the data MUST have originated from the owner; this is known as nonrepudiation as the owner cannot claim that encrypted data did not originate from them (of course, the private key may have been stolen but that is a different matter).</font></p> <font size="2"></font>  <p><font size="2">Translating this to the current scenario, in order for the client and service to successfully converse using certificates, the WCF client application must have access to the client’s private key and IIS (the receiving party) must have access to the client’s public key. Conversely, IIS must have access to the service private key and the client must have access to the service public key.</font></p> <font size="2"></font>  <p><font size="2">In an Active Directory domain, the public key certificate is ordinarily assigned to a domain account such that IIS can locate the certificate using </font><a href="https://technet.microsoft.com/en-us/library/cc770946(WS.10).aspx"><font size="2">Active Directory Domain Services</font></a><font size="2"> (ADDS). However, ADDS does not exist in a workgroup environment and so the client certificate public key list must be maintained within IIS itself.</font></p>  <h1><u>Methodology</u></h1>  <p>&#160;</p>  <h2>1) Create a trusted root certificate</h2>  <p><font size="2">The certificates in this article are issued by a certificate authority, in this case a trusted root certificate created using the makecert tool that ships with the Windows SDK.</font></p>  <ul>   <li><font size="2">Create a folder somewhere on the file system and, in a command window, change the directory to match the newly created folder </font><font size="2">&#160; </font></li>    <li><font size="2">Run the following command to create a root certificate (do not define a password) </font>      <ul><font size="2"></font>        <li><font size="2">&quot;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\makecert&quot; -r -pe -n &quot;CN=Test Root Authority&quot; -ss CA -sr CurrentUser -a sha1 -sky signature -cy authority -sv TestRoot.pvk TestRoot.cer</font></li>     </ul>      <p>&#160;</p>   </li> </ul>  <h2>2) Install the client certificate with private key</h2>  <p><font size="2">The client application, as owner of the client certificate, needs access to the private key at runtime. We are going to create an interactive client (e.g. – Console, WinForm, Silverlight, Internet Explorer etc.), and so the certificate will be installed in the Current User – Personal store. If the client was non-interactive (e.g. – NT service) the certificate would be installed in the Local Machine – Personal store.</font></p> <font size="2"></font>  <p><font size="2">Additionally, as the client certificate has been issued from a trusted certificate authority (CA), the root certificate created in 1) must also be installed.</font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="2">From the folder where TestRoot.cer is located, create and install a client certificate by running the following in a command window </font>      <ul><font size="2"></font>        <li><font size="2">&quot;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\makecert&quot; -n &quot;CN=Test Client&quot; -ic &quot;TestRoot.cer&quot; -iv &quot;TestRoot.pvk&quot; -a sha1 -sky exchange -pe -sr currentuser -ss my &quot;TestClient.cer&quot; </font></li>       <font size="2"></font></ul>     <font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Open a snap-in window </font>      <ul><font size="2"></font>        <li><font size="2">Start – Run – mmc </font></li>       <font size="2"></font>        <li><font size="2">Add/Remove snap-in </font></li>       <font size="2"></font>        <li><font size="2">Ctrl-M </font></li>       <font size="2"></font>        <li><font size="2">Add a Certificates snap-in for ‘My user account’ </font></li>       <font size="2"></font></ul>     <font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Expand the (Trusted Root Certification Authorities)/Certificates node </font></li>   <font size="2"></font>    <li><font size="2">Right click the Certificates folder and choose All Tasks – Import </font></li>   <font size="2"></font>    <li><font size="2">Browse to TestRoot.cer </font></li>   <font size="2"></font>    <li><font size="2">Click through the remaining windows and finish</font></li> </ul>  <p><font size="2"></font></p>  <h2>3) Install the service certificate with private key</h2>  <p><font size="2">The service, as owner of a service certificate, needs access to the private key at runtime. As the service is non-interactive (i.e. – it is not running under the context of a logged-on user), the certificate will be installed in the Local Machine – Personal store.</font></p> <font size="2"></font>  <p><font size="2">Additionally, as the service certificate has been issued from a trusted certificate authority (CA), the root certificate for the CA must also be installed so that the chain of trust can be verified.</font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="2">From the folder where TestRoot.cer is located, install the service certificate by running the following in a command window </font>      <ul><font size="2"></font>        <li><font size="2">&quot;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\makecert&quot; -n &quot;CN=www.mydataservice.com&quot; -ic &quot;TestRoot.cer&quot; -iv &quot;TestRoot.pvk&quot; -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -pe -sr LocalMachine -ss my TestDataService.cer </font></li>       <font size="2"></font></ul>     <font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Open a snap-in window </font>      <ul><font size="2"></font>        <li><font size="2">Start – Run – mmc </font></li>       <font size="2"></font>        <li><font size="2">Add/Remove snap-in </font></li>       <font size="2"></font>        <li><font size="2">Ctrl-M </font></li>       <font size="2"></font>        <li><font size="2">Add a Certificates snap-in for ‘Computer account’ </font></li>       <font size="2"></font></ul>     <font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Expand the (Trusted Root Certification Authorities)/Certificates node </font></li>   <font size="2"></font>    <li><font size="2">Right click the Certificates folder and choose All Tasks – Import </font></li>   <font size="2"></font>    <li><font size="2">Browse to TestRoot.cer </font></li>   <font size="2"></font>    <li><font size="2">Click through the remaining windows and finish</font></li> </ul>  <p><font size="2"></font></p>  <h2>4) Export the client public key certificate</h2>  <p><font size="2">IIS needs access to the client’s public key certificate. In this section the certificate is exported for later use.</font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="2">Open a snap-in window (or use the same window as 2)) </font>      <ul><font size="2"></font>        <li><font size="2">Start – Run – mmc </font></li>       <font size="2"></font>        <li><font size="2">Add/Remove snap-in </font></li>       <font size="2"></font>        <li><font size="2">Ctrl-M </font></li>       <font size="2"></font>        <li><font size="2">Add a Certificates snap-in for ‘My user account’ </font></li>       <font size="2"></font></ul>     <font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Expand the (Certificates – Current User)/Personal/Certificates node </font></li>   <font size="2"></font>    <li><font size="2">Right click the Test Client certificate and choose All Tasks – Export (Do not export the primary key) </font>      <ul><font size="2"></font>        <li><font size="2">N.B. - Exporting the private key will not cause problems but remember that the private key is for the client ALONE </font></li>       <font size="2"></font></ul>     <font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Save the certificate as TestClient_Public.cer (Base-64 encoded X.509)</font></li> </ul>  <p><font size="2"></font></p>  <h2>5) Export the service public key certificate</h2>  <p><font size="2">The WCF client needs access to the service public key certificate. In this section the certificate is exported for later use.</font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="2">Open a snap-in window (or use the same window as 3)) </font></li>    <ul><font size="2"></font>      <li><font size="2">Start – Run – mmc </font></li>     <font size="2"></font>      <li><font size="2">Add/Remove snap-in </font></li>     <font size="2"></font>      <li><font size="2">Ctrl-M </font></li>     <font size="2"></font>      <li><font size="2">Add a Certificates snap-in for ‘Computer account’ </font></li>     <font size="2"></font></ul>    <li><font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Expand the (Certificates – Local Computer)/Personal/Certificates node </font></li>   <font size="2"></font>    <li><font size="2">Right click the www.testdataservice.com certificate and choose All Tasks – Export (Do not export the primary key) </font>      <ul><font size="2"></font>        <li><font size="2">Exporting the private key will not cause problems but remember that the private key is for the service ALONE </font></li>       <font size="2"></font></ul>     <font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Save the certificate as TestDataService_Public.cer (Base-64 encoded X.509)</font> </li> </ul>  <p>&#160;</p>  <h2>6) Create a WCF data service</h2>  <p><font size="2">In this section a basic WCF data service is created in order to secure it using mutual authentication.</font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="3"><font size="2">In Visual Studio 2010, create a new empty solution called MyDataServices</font> </font></li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/5270.image_29DB9F89.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/5270.image_5F00_29DB9F89.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/2543.image_thumb_4192D6EF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/2543.image_5F00_thumb_5F00_4192D6EF.png" width="730" height="505" /></font></a></p>  <ul>   <li><font size="3"><font size="2">Add a new ASP.NET empty web application called MyDataService</font> </font></li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/3632.image_6DCF5DD3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/3632.image_5F00_6DCF5DD3.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/7532.image_thumb_45507BBF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/7532.image_5F00_thumb_5F00_45507BBF.png" width="729" height="504" /></font></a></p>  <ul>   <li><font size="2">Add a new empty ADO.NET Entity Data Model item to MyDataService called MyDataServiceModel.edmx (empty model)</font> </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/4718.image_1C6566B6.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/4718.image_5F00_1C6566B6.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/6787.image_thumb_6209F0D4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/6787.image_5F00_thumb_5F00_6209F0D4.png" width="727" height="503" /></font></a></p>  <ul>   <li><font size="2">Add a new WCF Data Service item to MyDataService called MyDataServiceImp.svc</font> </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/8424.image_6059%.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/8424.image_5F00_60592500.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/8422.image_thumb_37DA42EC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/8422.image_5F00_thumb_5F00_37DA42EC.png" width="726" height="502" /></font></a></p>  <ul>   <li><font size="2">Open the code behind file for MyDataServiceImp.svc and add MyDataServiceModelContainer into the class definition</font> </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/4721.image_6416C9D0.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/4721.image_5F00_6416C9D0.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/7853.image_thumb_50896A2F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/7853.image_5F00_thumb_5F00_50896A2F.png" width="724" height="519" /></font></a><font size="3">&#160;</font></p>  <ul>   <li><font size="2">Open MyDataServiceModel.edmx </font></li>   <font size="2"></font>    <li><font size="2">Right click anywhere on the screen and choose to Generate Database from Model </font></li>   <font size="2"></font>    <li><font size="2">Create a new data connection to SQL Server if one does not already exist </font></li>   <font size="2"></font>    <li><font size="2">Build the solution</font></li> </ul>  <p><font size="2"></font></p>  <h2>7) Host the data service in IIS</h2>  <ul>   <li><font size="2">Open IIS manager </font></li>   <font size="2"></font>    <li><font size="2">Start – Administrative Tools – Internet Information Services (IIS) Manager </font></li>   <font size="2"></font>    <li><font size="2">Create a new website called ‘My Data Service’ </font></li>   <font size="2"></font>    <li><font size="2">Point the physical path to the data service created in 6) </font></li>   <font size="2"></font>    <li><font size="2">Choose a binding type of https and select the www.mydataservice.com SSL certificate</font> </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/3731.image_4E6C6B66.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/3731.image_5F00_4E6C6B66.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/1425.image_thumb_3F558C8C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/1425.image_5F00_thumb_5F00_3F558C8C.png" width="507" height="499" /></font></a></p>  <ul>   <li><font size="2">Modify the app pool under which the website is running so that the .NET framework version is v4.0.30319</font> </li> </ul>  <p><font size="3"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/6470.image_72B14FE8.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/6470.image_5F00_72B14FE8.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/6470.image_thumb_23D08A89.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/6470.image_5F00_thumb_5F00_23D08A89.png" width="318" height="289" /></font></a></font></p>  <ul>   <li><font size="2">Add a hosts file entry for ‘127.0.0.1 www.mydataservice.com’ </font></li>   <font size="2"></font>    <li><font size="2">Via Windows Explorer, give ‘Everyone’ full control of the MyDataService folder </font>      <ul><font size="2"></font>        <li><font size="2">N.B. – this is a shortcut for keeping the blog post succinct. Such permissions should not be an option for a production deployment</font> </li>     </ul>   </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/3250.image_697514A7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/3250.image_5F00_697514A7.png"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/5238.image_thumb_7934A9AB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/5238.image_5F00_thumb_5F00_7934A9AB.png" width="507" height="319" /></a></p>  <p>&#160;</p>  <h2>8) Create a WCF client</h2>  <p><font size="2">In order to make life a little easier, we will create and configure the WCF client before locking down the service.</font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="2">Add a new Console Application project called MyDataServiceClient to MyDataServices </font></li>   <font size="2"></font>    <li><font size="2">Right click the project and choose to ‘Add Service Reference’ </font></li>   <font size="2"></font>    <li><font size="2">Enter an address of https://www.mydataservice.com/mydataserviceimp.svc </font></li>   <font size="2"></font>    <li><font size="2">Click Go </font></li>   <font size="2"></font>    <li><font size="2">Once the service has been discovered give it the namespace MyDataServiceEntities</font></li> </ul>  <p><font size="2"></font></p>  <h2>9) Enable client certificate authentication in IIS</h2>  <p><font size="2">Both IIS and the WCF data service must be configured for client certificate authentication, otherwise there is a mismatch and a service activation failure similar to ‘<i>The SSL settings for the service 'SslRequireCert' does not match those of the IIS 'Ssl'</i>’ will occur.</font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="2">Open IIS manager </font>      <ul><font size="2"></font>        <li><font size="2">Start – Administrative Tools – Internet Information Services (IIS) Manager </font></li>       <font size="2"></font></ul>     <font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Highlight the WCF data service website and double click ‘SSL Settings’</font> </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/7875.image_65A74A0A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/7875.image_5F00_65A74A0A.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/1018.image_thumb_49B61512.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/1018.image_5F00_thumb_5F00_49B61512.png" width="728" height="328" /></font></a></p>  <ul>   <li><font size="3"><font size="2">Configure IIS as below</font> </font></li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/1033.image_19ABC391.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/1033.image_5F00_19ABC391.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/7317.image_thumb_7E26C18D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/7317.image_5F00_thumb_5F00_7E26C18D.png" width="727" height="327" /></font></a></p>  <p>&#160;</p>  <h2>10) Register the client public key certificate with the service</h2>  <p><font size="2">In this section the public key certificate from 4) is registered with the data service website.</font></p> <font size="2"></font>  <p><font size="2">Client certificates can be mapped in a ‘one to one’ or ‘many to one’ relationship with Windows accounts. ‘one to one’ means that a client certificate is linked to a single Windows account. ‘many to one’ means that many client certificates are assigned to a single Windows account.</font></p> <font size="2"></font>  <p><font size="2">In this post we will use the ‘one to one’ relationship but the ‘many to one’ relationship does not differ greatly </font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="2">Highlight the MyDataService website and double click ‘Configuration Editor’</font> </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/3681.image_7C75F5B9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/3681.image_5F00_7C75F5B9.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/3175.image_thumb_7AC529E5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/3175.image_5F00_thumb_5F00_7AC529E5.png" width="728" height="379" /></font></a></p>  <ul>   <li><font size="3"><font size="2">Choose the ‘oneToOneMappings’ section</font> </font></li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/7713.image_1F76415D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/7713.image_5F00_1F76415D.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/4251.image_thumb_2EC9A36C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/4251.image_5F00_thumb_5F00_2EC9A36C.png" width="728" height="279" /></font></a></p>  <ul>   <li><font size="2">Click Add </font></li>   <font size="2"></font>    <li><font size="2">Set the entry as ‘enabled’ = true </font></li>   <font size="2"></font>    <li><font size="2">Set the username with associated password as that of the local administrator </font></li>   <font size="2"></font>    <li><font size="2">In production this would most likely be a service account with reduced privileges </font></li>   <font size="2"></font>    <li><font size="2">Right click the TestClient_Public.cer file from 4) and choose to edit in Notepad </font></li>   <font size="2"></font>    <li><font size="2">Ensure that the block between, but not including, ‘-----BEGIN CERTIFICATE-----‘ and ‘-----END CERTIFICATE-----‘, is all on a single line (it is not by default) </font></li>   <font size="2"></font>    <li><font size="3"><font size="2">Copy and paste the block into the ‘certificate’ field so that the resulting entry is as below</font> </font></li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/8080.image_6CE2BE1D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/8080.image_5F00_6CE2BE1D.png"><font size="3"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/6811.image_thumb_3287483C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/6811.image_5F00_thumb_5F00_3287483C.png" width="730" height="389" /></font></a></p>  <ul>   <li><font size="2">Close the window </font></li>   <font size="2"></font>    <li><font size="2">Click Apply</font></li> </ul>  <p><font size="2"></font></p>  <h2>11) Mandate client certificate authentication for the data service</h2>  <p><font size="2">The data service must also be configured to mandate client certificate authentication.</font></p> <font size="2"></font>  <p><font size="2">In web.config, overwrite the &lt;system.serviceModel&gt; element with the following</font></p>  <div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9b584e56-f0ed-49af-9e03-966260daaf85" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">&lt;</span><span style="color:#a31515">system.serviceModel</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">bindings</span><span style="color:#0000ff">&gt;</span></li> <li>    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">webHttpBinding</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">binding</span><span style="color:#0000ff"> </span><span style="color:#ff0000">name</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">mutual</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li>        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">security</span><span style="color:#0000ff"> </span><span style="color:#ff0000">mode</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">Transport</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">          <span style="color:#0000ff">&lt;</span><span style="color:#a31515">transport</span><span style="color:#0000ff"> </span><span style="color:#ff0000">clientCredentialType</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">Certificate</span>&quot;<span style="color:#0000ff"> /&gt;</span></li> <li>        <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">security</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">      <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">binding</span><span style="color:#0000ff">&gt;</span></li> <li>    <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">webHttpBinding</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">  <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">bindings</span><span style="color:#0000ff">&gt;</span></li> <li>  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">behaviors</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">endpointBehaviors</span><span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">behavior</span><span style="color:#0000ff"> </span><span style="color:#ff0000">name</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">mutual</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">webHttp</span><span style="color:#0000ff">/&gt;</span></li> <li>      <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">behavior</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">    <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">endpointBehaviors</span><span style="color:#0000ff">&gt;</span></li> <li>  <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">behaviors</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">serviceHostingEnvironment</span><span style="color:#0000ff"> </span><span style="color:#ff0000">aspNetCompatibilityEnabled</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">true</span>&quot;<span style="color:#0000ff"> /&gt;</span></li> <li>  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">services</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">service</span><span style="color:#0000ff"> </span><span style="color:#ff0000">name</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">MyDataService.MyDataServiceImp</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">endpoint</span><span style="color:#0000ff"> </span><span style="color:#ff0000">contract</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">System.Data.Services.IRequestHandler</span>&quot;</li> <li style="background: #f3f3f3">                <span style="color:#0000ff"></span><span style="color:#ff0000">binding</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">webHttpBinding</span>&quot;</li> <li>                <span style="color:#0000ff"></span><span style="color:#ff0000">bindingConfiguration</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">mutual</span>&quot;</li> <li style="background: #f3f3f3">                <span style="color:#0000ff"></span><span style="color:#ff0000">behaviorConfiguration</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">mutual</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">endpoint</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">    <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">service</span><span style="color:#0000ff">&gt;</span></li> <li>  <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">services</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">&lt;/</span><span style="color:#a31515">system.serviceModel</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div> <font size="3"></font>  <ul></ul>  <p><font size="2">The contents of the &lt;webHttpBinding&gt; element mandate that client certificate authentication at the transport level is required for the binding. The &lt;services&gt;/&lt;service&gt;/&lt;endpoint&gt; element describes the contract that all WCF data services must adhere to.</font> </p>  <ul></ul>  <h2>12) Register the service public key certificate with the client</h2>  <p><font size="2">As this article is concerned with mutual authentication then it is not sufficient for only the service to authenticate the client. In addition, the client must be certain that it is calling the right endpoint. One way to achieve this is to store the service public key certificate with the client so that during runtime, the SSL certificate presented by the service can be compared against the locally stored version. In this way the client can be sure that it is calling the correct SSL endpoint located at </font><font size="2">www.mydataservice.com</font><font size="2"> and that it has not been phished into calling another endpoint with the same URL but different SSL certificate.</font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="2">Open a snap-in window </font>      <ul><font size="2"></font>        <li><font size="2">Start – Run – mmc </font></li>       <font size="2"></font>        <li><font size="2">Add/Remove snap-in </font></li>       <font size="2"></font>        <li><font size="2">Ctrl-M </font></li>       <font size="2"></font>        <li><font size="2">Add a Certificates snap-in for ‘My user account’ </font></li>       <font size="2"></font></ul>     <font size="2"></font></li>   <font size="2"></font>    <li><font size="2">Expand the (Certificates – Current User)/Personal/Certificates node </font></li>   <font size="2"></font>    <li><font size="2">Right click the Certificates folder and choose All Tasks – Import </font></li>   <font size="2"></font>    <li><font size="2">Browse to TestDataService_Public.cer that was created in 6) </font></li>   <font size="2"></font>    <li><font size="2">Click through the remaining windows and finish</font></li> </ul>  <p><font size="3"></font></p>  <h2>13) Update the WCF client to verify the service certificate</h2>  <p><font size="2">As the service is now locked down, the client will not be able to use it without undergoing some modification. </font></p> <font size="2"></font>  <ul><font size="2"></font>    <li><font size="2">Overwrite Program.cs with the following</font></li> </ul>  <div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a82ca58d-9e0e-4d5f-8b45-5efc2fb2bdc3" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">namespace</span> MyDataServiceClient</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">using</span> System;</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">using</span> System.Collections.Generic;</li> <li>    <span style="color:#0000ff">using</span> System.Net;</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">using</span> System.Net.Security;</li> <li>    <span style="color:#0000ff">using</span> System.Security.Cryptography.X509Certificates;</li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="color:#0000ff">class</span> <span style="color:#2b91af">Program</span></li> <li style="background: #f3f3f3">    {</li> <li>        <span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> MyDataServiceEntities.<span style="color:#2b91af">MyDataServiceModelContainer</span> entities = <span style="color:#0000ff">new</span> MyDataServiceEntities.<span style="color:#2b91af">MyDataServiceModelContainer</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">Uri</span>(<span style="color:#a31515">@&quot;https://www.mydataservice.com/mydataserviceimp.svc&quot;</span>));</li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> Main(<span style="color:#0000ff">string</span>[] args)</li> <li style="background: #f3f3f3">        {</li> <li>            <span style="color:#2b91af">X509Store</span> store = <span style="color:#0000ff">new</span> <span style="color:#2b91af">X509Store</span>(<span style="color:#2b91af">StoreName</span>.My, <span style="color:#2b91af">StoreLocation</span>.CurrentUser);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>            store.Open(<span style="color:#2b91af">OpenFlags</span>.ReadOnly);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="color:#2b91af">X509Certificate2Collection</span> certColl = store.Certificates.Find(<span style="color:#2b91af">X509FindType</span>.FindBySubjectDistinguishedName, <span style="color:#a31515">&quot;CN=Test Client&quot;</span>, <span style="color:#0000ff">false</span>);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>            entities.ClientCertificate = certColl[0];</li> <li style="background: #f3f3f3">&nbsp;</li> <li>            store.Close();</li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="color:#2b91af">ServicePointManager</span>.ServerCertificateValidationCallback +=</li> <li style="background: #f3f3f3">                <span style="color:#0000ff">delegate</span>(<span style="color:#0000ff">object</span> sender, <span style="color:#2b91af">X509Certificate</span> cert, <span style="color:#2b91af">X509Chain</span> chain, <span style="color:#2b91af">SslPolicyErrors</span> sslError)</li> <li>                {</li> <li style="background: #f3f3f3">                    <span style="color:#008000">// Validate the certificate</span></li> <li>                    store = <span style="color:#0000ff">new</span> <span style="color:#2b91af">X509Store</span>(<span style="color:#2b91af">StoreName</span>.My, <span style="color:#2b91af">StoreLocation</span>.CurrentUser);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>                    store.Open(<span style="color:#2b91af">OpenFlags</span>.ReadOnly);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>                    <span style="color:#2b91af">X509Certificate2Collection</span> serverCertColl = store.Certificates.Find(<span style="color:#2b91af">X509FindType</span>.FindBySubjectDistinguishedName, <span style="color:#a31515">&quot;CN=www.mydataservice.com&quot;</span>, <span style="color:#0000ff">false</span>);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>                    <span style="color:#2b91af">X509Certificate2</span> serverCert = serverCertColl[0];</li> <li style="background: #f3f3f3">&nbsp;</li> <li>                    store.Close();</li> <li style="background: #f3f3f3">&nbsp;</li> <li>                    <span style="color:#008000">// Make this as rigorous as necessary</span></li> <li style="background: #f3f3f3">                    <span style="color:#0000ff">return</span> serverCert.Thumbprint == (<span style="color:#0000ff">new</span> <span style="color:#2b91af">X509Certificate2</span>(cert)).Thumbprint;</li> <li>                };</li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="color:#008000">// Send the query to the data service context</span></li> <li style="background: #f3f3f3">            <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">object</span>&gt; result = entities.Execute&lt;<span style="color:#0000ff">object</span>&gt;(entities.BaseUri);</li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="color:#2b91af">Console</span>.WriteLine();</li> <li>            <span style="color:#2b91af">Console</span>.WriteLine(<span style="color:#a31515">&quot;**********&quot;</span>);</li> <li style="background: #f3f3f3">            <span style="color:#2b91af">Console</span>.WriteLine(<span style="color:#a31515">&quot;Success!!!&quot;</span>);</li> <li>            <span style="color:#2b91af">Console</span>.WriteLine(<span style="color:#a31515">&quot;**********&quot;</span>);</li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="color:#2b91af">Console</span>.ReadKey();</li> <li style="background: #f3f3f3">        }</li> <li>    }</li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div>  <ul></ul>  <pre class="csharpcode"><font size="3" face="Calibri"><font size="2" face="Segoe UI">Note that the ClientCertificate property of the proxy is not recognised; this represents the last piece of the puzzle. As there is no declarative configuration for the WCF client (i.e. - no &lt;system.serviceModel&gt; element was created in the client config file, unlike for, say, a standard SOAP based web service), the client certificate is hooked in programmatically by intercepting the underlying HttpWebRequest instance.</font></font></pre>
<font size="2"></font>

<ul><font size="2"></font>

  <li>
    <pre class="csharpcode"><font face="Segoe UI">Overwrite Reference.cs contained within the MyDataServiceEntities service reference, with the following</font></pre>
  </li>
</ul>

<div style="margin: 0px; padding: 0px; float: none; display: inline;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1afb0026-700d-47c7-95d3-c03fdd7c5d02" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div>
<div style="background: #ddd; overflow: auto">
<ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap">
<li><span style="color:#0000ff">namespace</span> MyDataServiceClient.MyDataServiceEntities</li>
<li style="background: #f3f3f3">{</li>
<li>    <span style="color:#0000ff">using</span> System.Data.Services.Client;</li>
<li style="background: #f3f3f3">    <span style="color:#0000ff">using</span> System.Net;</li>
<li>    <span style="color:#0000ff">using</span> System.Security.Cryptography.X509Certificates;</li>
<li style="background: #f3f3f3">&nbsp;</li>
<li>    <span style="color:#0000ff">public</span> <span style="color:#0000ff">partial</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">MyDataServiceModelContainer</span> : <span style="color:#0000ff">global</span>::System.Data.Services.Client.<span style="color:#2b91af">DataServiceContext</span></li>
<li style="background: #f3f3f3">    {</li>
<li>        <span style="color:#0000ff">private</span> <span style="color:#2b91af">X509Certificate</span> clientCertificate = <span style="color:#0000ff">null</span>;</li>
<li style="background: #f3f3f3">&nbsp;</li>
<li>        <span style="color:#0000ff">public</span> MyDataServiceModelContainer(<span style="color:#0000ff">global</span>::System.<span style="color:#2b91af">Uri</span> serviceRoot) :</li>
<li style="background: #f3f3f3">            <span style="color:#0000ff">base</span>(serviceRoot)</li>
<li>        {</li>
<li style="background: #f3f3f3">            <span style="color:#0000ff">this</span>.OnContextCreated();</li>
<li>        }</li>
<li style="background: #f3f3f3">&nbsp;</li>
<li>        <span style="color:#0000ff">partial</span> <span style="color:#0000ff">void</span> OnContextCreated();</li>
<li style="background: #f3f3f3">&nbsp;</li>
<li>        <span style="color:#0000ff">public</span> <span style="color:#2b91af">X509Certificate</span> ClientCertificate</li>
<li style="background: #f3f3f3">        {</li>
<li>            <span style="color:#0000ff">get</span></li>
<li style="background: #f3f3f3">            {</li>
<li>                <span style="color:#0000ff">return</span> clientCertificate;</li>
<li style="background: #f3f3f3">            }</li>
<li>            <span style="color:#0000ff">set</span></li>
<li style="background: #f3f3f3">            {</li>
<li>                <span style="color:#0000ff">if</span> (<span style="color:#0000ff">value</span> == <span style="color:#0000ff">null</span>)</li>
<li style="background: #f3f3f3">                {</li>
<li>                    <span style="color:#008000">// if the event has been hooked up before, we should remove it</span></li>
<li style="background: #f3f3f3">                    <span style="color:#0000ff">if</span> (clientCertificate != <span style="color:#0000ff">null</span>)</li>
<li>                        <span style="color:#0000ff">this</span>.SendingRequest -= <span style="color:#0000ff">this</span>.OnSendingRequest_AddCertificate;</li>
<li style="background: #f3f3f3">                }</li>
<li>                <span style="color:#0000ff">else</span></li>
<li style="background: #f3f3f3">                {</li>
<li>                    <span style="color:#008000">// hook up the event if its being set to something non-null</span></li>
<li style="background: #f3f3f3">                    <span style="color:#0000ff">if</span> (clientCertificate == <span style="color:#0000ff">null</span>)</li>
<li>                        <span style="color:#0000ff">this</span>.SendingRequest += <span style="color:#0000ff">this</span>.OnSendingRequest_AddCertificate;</li>
<li style="background: #f3f3f3">                }</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3">                clientCertificate = <span style="color:#0000ff">value</span>;</li>
<li>            }</li>
<li style="background: #f3f3f3">        }</li>
<li>&nbsp;</li>
<li style="background: #f3f3f3">        <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> OnSendingRequest_AddCertificate(<span style="color:#0000ff">object</span> sender, <span style="color:#2b91af">SendingRequestEventArgs</span> args)</li>
<li>        {</li>
<li style="background: #f3f3f3">            <span style="color:#0000ff">if</span> (<span style="color:#0000ff">null</span> != ClientCertificate)</li>
<li>                (args.Request <span style="color:#0000ff">as</span> <span style="color:#2b91af">HttpWebRequest</span>).ClientCertificates.Add(ClientCertificate);</li>
<li style="background: #f3f3f3">        }</li>
<li>    }</li>
<li style="background: #f3f3f3">}</li>
</ol>
</div>
</div>
</div>


<ul>&#160; <li><font size="2">Set MyDataServiceClient as the startup project </font></li>
  <font size="2"></font>

  <li><font size="2">Press F5</font> </li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/0550.image_49D24CAD.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/0550.image_5F00_49D24CAD.png"><img style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/0572.image_thumb_4FACF046.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67-metablogapi/0572.image_5F00_thumb_5F00_4FACF046.png" width="749" height="371" /></a></p>

<p><u></u></p>

<h1><u>Conclusion</u></h1>

<p><font size="2">In this article I have demonstrated a methodology for securing communication between a WCF client and a IIS hosted WCF data service, installed on a workgroup server, using mutual certificate authentication. While in many ways similar to mutual authentication scenarios described elsewhere, securing a WCF data service exhibits some unique characteristics that warranted documenting.</font></p>
<font size="2"></font>

<p><font size="2">I hope you find this useful.</font></p>

<p><em>Written by [BradleyCotier]</em></p>]]></content:encoded>
    </item>
    <item>
      <title>Windows Azure toolkit for Windows Phone 7</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/windows-azure-toolkit-for-windows-phone-7</link>
      <pubDate>Tue, 25 Oct 2011 08:55:00 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2011/10/25/windows-azure-toolkit-for-windows-phone-7/</guid>
      <description><![CDATA[Hi all
I am having great fun playing&nbsp;with this&nbsp;toolkit to see how WP7 apps can be...]]></description>
      <content:encoded><![CDATA[<p>Hi all</p>
<p>I am having great fun playing&nbsp;with <a title="https://watwp.codeplex.com/" href="https://watwp.codeplex.com/" target="_blank">this</a>&nbsp;toolkit to see how WP7 apps can be properly secured using the&nbsp;Azure Access Control Service (ACS).</p>
<p>I hit a couple of problems while trying to create a new 'Windows Phone Cloud Application' project in Visual Studio though, at the following screen:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/8255.dialog.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67/8255.dialog.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/8255.dialog.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-37-67/8255.dialog.png" /></a></p>
<p>1) Make sure the ACS&nbsp;namespace is just the &lt;namespace&gt; bit of&nbsp;<a href="https://<namespace>.accesscontrol.windows.net">https://&lt;namespace&gt;.accesscontrol.windows.net</a>. Fairly obvious I guess but I have been using appfabriclabs.com and assumed that the domain name part of the namespace would resolve the Azure environment I needed. Also, it follows from this that you MUST use the production Azure environment.</p>
<p>2) Make sure you don't use an old ACS namespace which is still at ACS V1. The toolkit will only work with V2 because only V2 supports the required federation protocols.</p>
<p>Later.</p>
<p>Brad</p>]]></content:encoded>
    </item>
    <item>
      <title>A quiz question</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/a-quiz-question</link>
      <pubDate>Thu, 11 Nov 2010 11:32:26 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2010/11/11/a-quiz-question/</guid>
      <description><![CDATA[Using the IXmlSerializable interface, create a class that will serialize XML to be exactly the same...]]></description>
      <content:encoded><![CDATA[<p>Using the IXmlSerializable interface, create a class that will serialize XML to be exactly the same as the following:</p>  <div id="codeSnippetWrapper">   <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">&lt;</span><span style="color: #800000">ns1:Root</span> <span style="color: #ff0000">xmlns:ns1</span><span style="color: #0000ff">=&quot;urn:myrootnamespace&quot;</span><span style="color: #0000ff">&gt;</span><br />    <span style="color: #0000ff">&lt;</span><span style="color: #800000">ns2:child</span> <span style="color: #ff0000">xmlns:ns2</span><span style="color: #0000ff">=&quot;urn:mychildnamespace&quot;</span><span style="color: #0000ff">&gt;</span><br />        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ns2:elementInChildNS</span> <span style="color: #0000ff">/&gt;</span><br />        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ns1:elementInRootNS</span> <span style="color: #0000ff">/&gt;</span><br />        <span style="color: #0000ff">&lt;</span><span style="color: #800000">elementInNoNS</span> <span style="color: #0000ff">/&gt;</span><br />    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">ns2:child</span><span style="color: #0000ff">&gt;</span><br /><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ns1:Root</span><span style="color: #0000ff">&gt;</span></pre>

  <br /></div>

<p>I couldn’t do it <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/37/67/metablogapi/4572.wlEmoticon-smile_636300C3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-37-67-metablogapi/4572.wlEmoticon_2D00_smile_5F00_636300C3.png" /></p>]]></content:encoded>
    </item>
    <item>
      <title>The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'</title>
      <link>https://docs.microsoft.com/archive/blogs/bradleycotier/the-http-request-is-unauthorized-with-client-authentication-scheme-negotiate-the-authentication-header-received-from-the-server-was-negotiatentlm</link>
      <pubDate>Mon, 11 Oct 2010 00:37:35 GMT</pubDate>
      <dc:creator><![CDATA[MonkeyTennis]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/bradleycotier/2010/10/11/the-http-request-is-unauthorized-with-client-authentication-scheme-negotiate-the-authentication-header-received-from-the-server-was-negotiatentlm/</guid>
      <description><![CDATA[In the course of enabling WCF services using Windows authentication, you may have hit this error. A...]]></description>
      <content:encoded><![CDATA[<p>In the course of enabling WCF services using Windows authentication, you may have hit this error. A Bing search will show that there are a myriad of reasons as to why this might occur.</p>  <p>However, before you get bogged down in the complexities of WCF bindings and IIS metadata, there ‘may’ be a simple fix. If the client and service are on the same machine and you experience the aforementioned error, check out this article:</p>  <p><a title="https://blogs.msdn.com/b/distributedservices/archive/2009/11/10/wcf-calling-wcf-service-hosted-in-iis-on-the-same-machine-as-client-throws-an-authentication-error.aspx" href="https://blogs.msdn.com/b/distributedservices/archive/2009/11/10/wcf-calling-wcf-service-hosted-in-iis-on-the-same-machine-as-client-throws-an-authentication-error.aspx">https://blogs.msdn.com/b/distributedservices/archive/2009/11/10/wcf-calling-wcf-service-hosted-in-iis-on-the-same-machine-as-client-throws-an-authentication-error.aspx</a></p>  <p>This was infuriatingly difficult to track down but once found, I couldn’t understand why it wasn’t top of the search engine results.</p>  <p>Hopefully this will give the matter a little more press.</p>  <p>Later.</p>  <p>Brad</p>]]></content:encoded>
    </item>
  </channel>
</rss>