<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" version="2.0">
  <channel>
    <title>Michiel van Otegem, IT Composer</title>
    <link>http://michiel.vanotegem.nl/</link>
    <description>Making IT work like a symphony</description>
    <language>en-us</language>
    <copyright>Michiel van Otegem</copyright>
    <lastBuildDate>Wed, 16 May 2012 14:14:18 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>michiel@aspnl.com</managingEditor>
    <webMaster>michiel@aspnl.com</webMaster>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=0c6b89df-684b-4280-ba57-2f5409020443</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,0c6b89df-684b-4280-ba57-2f5409020443.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,0c6b89df-684b-4280-ba57-2f5409020443.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=0c6b89df-684b-4280-ba57-2f5409020443</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
When a Security Token Service (STS) creates a token, that token has an absolute expiration.
Usually this is about 60 minutes, after which the Relying Party (RP) has to send the
user back to the STS to acquire a new token. When using Windows Identity Foundation
(WIF) in ASP.NET (so for passive federation), this is the default behavior, because
the SessionAuthenticationModule stores the token in the FedAuth cookie and checks
that token on each request.
</p>
        <h3>What’s the problem?
</h3>
        <p>
I hear you thinking “Cool, WIF takes care of all that for me”, and that is cool. But
there’s also a nasty side effect, one which all web developers have encountered in
a different context: sessions. If a user logs in, starts filling out some form, and
then gets interrupted by a phone call, chances are that the session expires. This
can lead to problems when the user submits the form, because the user has to log in
again. The original posted data gets lost in the process, much to the frustration
of the user. Because sessions use sliding expiration the problem is minor. But with
absolute expiration, expiration can wreak havoc even if the user posts a form just
a minute after the form was presented to the user.
</p>
        <h3>Solving the problem
</h3>
        <p>
There are several ways to solve the problem outlined above:
</p>
        <ol>
          <li>
Don’t use the SessionAuthenticationModule. 
</li>
          <li>
Modify the stored token to implement sliding expiration. 
</li>
          <li>
Force reacquiring a token in the background, so you can control when this happens.</li>
        </ol>
        <p>
          <strong>Ditching the SessionAuthenticationModule</strong>
          <br />
Not using the SessionAuthenticationModule appears to be simple. Just remove it from
web.config and you’re done. However, if you remove it, you have to ensure a user stays
logged in after receiving the token, and you need to keep track of the received claims.
This means you need to use a cookie or session data to keep track of the user. Basically
you would be recreating what the SessionAuthenticationModule does for you for free.
</p>
        <p>
          <strong>Making token expiration sliding</strong>
          <br />
This is actually easier than ditching the SessionAuthenticationModule. All you have
to do is handle the SessionSecurityTokenReceived event and modify the ValidTo property
of the token, as shown in this <a href="http://social.msdn.microsoft.com/Forums/en/Geneva/thread/a048694c-3548-4b4d-9bb3-0589c888fd02">MSDN
Forums post</a>.
</p>
        <p>
Tip: You can hookup the event in the Application_Start event in global.asx using FederatedAuthentication.SessionAuthenticationModule
to point to the module.
</p>
        <p>
          <strong>Force reacquiring a token</strong>
          <br />
The above methods work fine, but have some drawbacks. One of these is the fact that
Single Sign-On (SSO) no longer works properly if a user spends too long in a single
application. This is because the login session with the Identity Provider will expire
at some point. Another issue arises if you want to use delegation or impersonation
when you call a web service. WS-Trust 1.4 supports delegation (ActAs) and impersonation
(OnBehalfOf). Even though WIF officially implements WS-Trust 1.3, WIF does support
these constructs. When calling web services from a web application, using delegation
is a recommended practice, because it greatly improves the security. The reason is
that in order for the web application to make the web service call on your behalf,
it needs to acquire a token from the STS, based on the original token. This means
a malicious user would need that token in order to make the web service call. Breaking
into the web application is not enough.
</p>
        <p>
So, how can you ensure you get a new token once in a while? Although the implementation
is somewhat more difficult, the principle is simple: logout of the RP. That triggers
the RP to re-authenticate the user by redirecting to the STS. As long as the user
is still known in the STS, a new token is transparently given out. You can do this
in roughly two ways: in an invisible iframe that does this process under the covers
or in the main request stream. The latter is more visible to the user and requires
you to bring the user back to where he was before the logout was forced, which is
slightly more complicated than a simple redirect. The iframe solution is more elegant,
because it does not interrupt the main working process. Basically all you have to
do is point the iframe to a handler that logs the user out if necessary, triggering
the re-authentication process when necessary and coming back to the handler to produce
an empty HTML page. The handler to do this is shown in the code below.
</p>
        <pre>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> System; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> System.Configuration; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> System.Globalization; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> System.IdentityModel.Tokens; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> System.Threading; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> System.Web; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> Microsoft.IdentityModel.Claims; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">using</span> Microsoft.IdentityModel.Web; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">namespace</span> WebApp
{ <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
HTTP Handler triggering token renewal when this is necessary.</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">class</span> TokenRenewalHandler
: IHttpHandler { <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
The default number of minutes before the token expires when renewal should be triggerd.</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">private</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">const</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> DefaultTokenRenewalWindow <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> 20; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
Value container for the TokenRenewalWindow</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">private</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> m_TokenRenewalWindow <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> 0; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
Number of minutes before the token expires when renewal should be triggerd.</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;remarks&gt;Should be less or equal to the session timeout.&lt;/remarks&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">protected</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> TokenRenewalWindow
{ get { <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span> (m_TokenRenewalWindow
== 0) { <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span> securityTokenRenewalWindow; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span> (!<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">int</span>.TryParse(
ConfigurationManager.AppSettings[<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"SecurityTokenRenewalWindow"</span>],
NumberStyles.Integer, CultureInfo.InvariantCulture, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">out</span> securityTokenRenewalWindow))
{ securityTokenRenewalWindow <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> DefaultTokenRenewalWindow;
} m_TokenRenewalWindow <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> securityTokenRenewalWindow;
} <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">return</span> m_TokenRenewalWindow;
} } <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
Handles the HTTP reqyest and forces a signout to renew the token if necessary.</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">///
&lt;/summary&gt;</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">void</span> ProcessRequest(HttpContext
context) { SecurityToken token <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>;
IClaimsPrincipal principal <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> Thread.CurrentPrincipal <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">as</span> IClaimsPrincipal; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span> (principal
!<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span> &amp;&amp;
principal.Identities.Count &gt; 0) { token <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> principal.Identities[0].BootstrapToken; <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span> (token
!<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>)
{ DateTime tokenExpirationTime <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> DateTime.Now.ToUniversalTime().AddMinutes(TokenRenewalWindow); <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span> (token.ValidTo.ToUniversalTime().CompareTo(tokenExpirationTime)
&lt; 0) { <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">if</span> (FederatedAuthentication.WSFederationAuthenticationModule
!<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">null</span>)
{ <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">//
Force sign-out.</span> FederatedAuthentication.WSFederationAuthenticationModule.SignOut(<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">false</span>);
} <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">//
Redirect to this handler to force a new sign-in request to the STS</span> context.Response.Redirect(context.Request.RawUrl, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">true</span>);
} } } <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px">//
Return an empty HTML page</span> context.Response.ContentType <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span><span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"text/html"</span>;
context.Response.Write(<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"&lt;html&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;"</span>);
} <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">bool</span> IsReusable
{ get { <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">return</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">false</span>;
} } } }</span>
        </pre>
        <img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=0c6b89df-684b-4280-ba57-2f5409020443" />
      </body>
      <title>Dealing with Token Timeout in Windows Identity Foundation</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,0c6b89df-684b-4280-ba57-2f5409020443.aspx</guid>
      <link>http://michiel.vanotegem.nl/2012/05/16/DealingWithTokenTimeoutInWindowsIdentityFoundation.aspx</link>
      <pubDate>Wed, 16 May 2012 14:14:18 GMT</pubDate>
      <description>&lt;p&gt;
When a Security Token Service (STS) creates a token, that token has an absolute expiration.
Usually this is about 60 minutes, after which the Relying Party (RP) has to send the
user back to the STS to acquire a new token. When using Windows Identity Foundation
(WIF) in ASP.NET (so for passive federation), this is the default behavior, because
the SessionAuthenticationModule stores the token in the FedAuth cookie and checks
that token on each request.
&lt;/p&gt;
&lt;h3&gt;What’s the problem?
&lt;/h3&gt;
&lt;p&gt;
I hear you thinking “Cool, WIF takes care of all that for me”, and that is cool. But
there’s also a nasty side effect, one which all web developers have encountered in
a different context: sessions. If a user logs in, starts filling out some form, and
then gets interrupted by a phone call, chances are that the session expires. This
can lead to problems when the user submits the form, because the user has to log in
again. The original posted data gets lost in the process, much to the frustration
of the user. Because sessions use sliding expiration the problem is minor. But with
absolute expiration, expiration can wreak havoc even if the user posts a form just
a minute after the form was presented to the user.
&lt;/p&gt;
&lt;h3&gt;Solving the problem
&lt;/h3&gt;
&lt;p&gt;
There are several ways to solve the problem outlined above:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Don’t use the SessionAuthenticationModule. 
&lt;li&gt;
Modify the stored token to implement sliding expiration. 
&lt;li&gt;
Force reacquiring a token in the background, so you can control when this happens.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;strong&gt;Ditching the SessionAuthenticationModule&lt;/strong&gt;
&lt;br&gt;
Not using the SessionAuthenticationModule appears to be simple. Just remove it from
web.config and you’re done. However, if you remove it, you have to ensure a user stays
logged in after receiving the token, and you need to keep track of the received claims.
This means you need to use a cookie or session data to keep track of the user. Basically
you would be recreating what the SessionAuthenticationModule does for you for free.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Making token expiration sliding&lt;/strong&gt; 
&lt;br&gt;
This is actually easier than ditching the SessionAuthenticationModule. All you have
to do is handle the SessionSecurityTokenReceived event and modify the ValidTo property
of the token, as shown in this &lt;a href="http://social.msdn.microsoft.com/Forums/en/Geneva/thread/a048694c-3548-4b4d-9bb3-0589c888fd02"&gt;MSDN
Forums post&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Tip: You can hookup the event in the Application_Start event in global.asx using FederatedAuthentication.SessionAuthenticationModule
to point to the module.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Force reacquiring a token&lt;/strong&gt;
&lt;br&gt;
The above methods work fine, but have some drawbacks. One of these is the fact that
Single Sign-On (SSO) no longer works properly if a user spends too long in a single
application. This is because the login session with the Identity Provider will expire
at some point. Another issue arises if you want to use delegation or impersonation
when you call a web service. WS-Trust 1.4 supports delegation (ActAs) and impersonation
(OnBehalfOf). Even though WIF officially implements WS-Trust 1.3, WIF does support
these constructs. When calling web services from a web application, using delegation
is a recommended practice, because it greatly improves the security. The reason is
that in order for the web application to make the web service call on your behalf,
it needs to acquire a token from the STS, based on the original token. This means
a malicious user would need that token in order to make the web service call. Breaking
into the web application is not enough.
&lt;/p&gt;
&lt;p&gt;
So, how can you ensure you get a new token once in a while? Although the implementation
is somewhat more difficult, the principle is simple: logout of the RP. That triggers
the RP to re-authenticate the user by redirecting to the STS. As long as the user
is still known in the STS, a new token is transparently given out. You can do this
in roughly two ways: in an invisible iframe that does this process under the covers
or in the main request stream. The latter is more visible to the user and requires
you to bring the user back to where he was before the logout was forced, which is
slightly more complicated than a simple redirect. The iframe solution is more elegant,
because it does not interrupt the main working process. Basically all you have to
do is point the iframe to a handler that logs the user out if necessary, triggering
the re-authentication process when necessary and coming back to the handler to produce
an empty HTML page. The handler to do this is shown in the code below.
&lt;/p&gt;
&lt;pre&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; System; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; System.Configuration; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; System.Globalization; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; System.IdentityModel.Tokens; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; System.Threading; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; System.Web; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; Microsoft.IdentityModel.Claims; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;using&lt;/span&gt; Microsoft.IdentityModel.Web; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;namespace&lt;/span&gt; WebApp
{ &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
HTTP Handler triggering token renewal when this is necessary.&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;class&lt;/span&gt; TokenRenewalHandler
: IHttpHandler { &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
The default number of minutes before the token expires when renewal should be triggerd.&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;private&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;const&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; DefaultTokenRenewalWindow &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; 20; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
Value container for the TokenRenewalWindow&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;private&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; m_TokenRenewalWindow &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; 0; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
Number of minutes before the token expires when renewal should be triggerd.&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;remarks&amp;gt;Should be less or equal to the session timeout.&amp;lt;/remarks&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;protected&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; TokenRenewalWindow
{ get { &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt; (m_TokenRenewalWindow
== 0) { &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt; securityTokenRenewalWindow; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt; (!&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;int&lt;/span&gt;.TryParse(
ConfigurationManager.AppSettings[&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"SecurityTokenRenewalWindow"&lt;/span&gt;],
NumberStyles.Integer, CultureInfo.InvariantCulture, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;out&lt;/span&gt; securityTokenRenewalWindow))
{ securityTokenRenewalWindow &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; DefaultTokenRenewalWindow;
} m_TokenRenewalWindow &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; securityTokenRenewalWindow;
} &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;return&lt;/span&gt; m_TokenRenewalWindow;
} } &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
Handles the HTTP reqyest and forces a signout to renew the token if necessary.&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;void&lt;/span&gt; ProcessRequest(HttpContext
context) { SecurityToken token &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;;
IClaimsPrincipal principal &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; Thread.CurrentPrincipal &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;as&lt;/span&gt; IClaimsPrincipal; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt; (principal
!&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt; &amp;amp;&amp;amp;
principal.Identities.Count &amp;gt; 0) { token &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; principal.Identities[0].BootstrapToken; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt; (token
!&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;)
{ DateTime tokenExpirationTime &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; DateTime.Now.ToUniversalTime().AddMinutes(TokenRenewalWindow); &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt; (token.ValidTo.ToUniversalTime().CompareTo(tokenExpirationTime)
&amp;lt; 0) { &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;if&lt;/span&gt; (FederatedAuthentication.WSFederationAuthenticationModule
!&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;null&lt;/span&gt;)
{ &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;//
Force sign-out.&lt;/span&gt; FederatedAuthentication.WSFederationAuthenticationModule.SignOut(&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;false&lt;/span&gt;);
} &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;//
Redirect to this handler to force a new sign-in request to the STS&lt;/span&gt; context.Response.Redirect(context.Request.RawUrl, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;true&lt;/span&gt;);
} } } &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: green; FONT-SIZE: 11px"&gt;//
Return an empty HTML page&lt;/span&gt; context.Response.ContentType &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"text/html"&lt;/span&gt;;
context.Response.Write(&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;);
} &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;bool&lt;/span&gt; IsReusable
{ get { &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;return&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;false&lt;/span&gt;;
} } } }&lt;/span&gt;&lt;/pre&gt;&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=0c6b89df-684b-4280-ba57-2f5409020443" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,0c6b89df-684b-4280-ba57-2f5409020443.aspx</comments>
      <category>ASP.NET</category>
      <category>English</category>
      <category>Security</category>
      <category>Windows Identity Foundation</category>
    </item>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=62ffbc62-6ee2-4f0e-94f5-575ca7f516bb</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,62ffbc62-6ee2-4f0e-94f5-575ca7f516bb.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,62ffbc62-6ee2-4f0e-94f5-575ca7f516bb.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=62ffbc62-6ee2-4f0e-94f5-575ca7f516bb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Bedankt allemaal voor het bezoeken van de sessie van <a href="http://cloudythoughts.siadis.com/">Patriek
van Dorp</a> en mijzelf over Windows Identity Foundation op <a href="http://www.devnetnoord.nl">devNetNoord</a>.
Je kunt <a href="http://michiel.vanotegem.nl/content/binary/devNetNoord_WIF.pptx">hier
de slides downloaden (1,92 MB)</a></p>
.<img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=62ffbc62-6ee2-4f0e-94f5-575ca7f516bb" /></body>
      <title>Slides devNetNoord presentatie 22 maart 2012</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,62ffbc62-6ee2-4f0e-94f5-575ca7f516bb.aspx</guid>
      <link>http://michiel.vanotegem.nl/2012/03/26/SlidesDevNetNoordPresentatie22Maart2012.aspx</link>
      <pubDate>Mon, 26 Mar 2012 07:03:10 GMT</pubDate>
      <description>&lt;p&gt;
Bedankt allemaal voor het bezoeken van de sessie van &lt;a href="http://cloudythoughts.siadis.com/"&gt;Patriek
van Dorp&lt;/a&gt; en mijzelf over Windows Identity Foundation op &lt;a href="http://www.devnetnoord.nl"&gt;devNetNoord&lt;/a&gt;.
Je kunt &lt;a href="http://michiel.vanotegem.nl/content/binary/devNetNoord_WIF.pptx"&gt;hier
de slides downloaden (1,92 MB)&lt;/a&gt;
&lt;/p&gt;
.&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=62ffbc62-6ee2-4f0e-94f5-575ca7f516bb" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,62ffbc62-6ee2-4f0e-94f5-575ca7f516bb.aspx</comments>
      <category>.NET</category>
      <category>Evenementen</category>
      <category>Nederlands</category>
      <category>Security</category>
      <category>Windows Identity Foundation</category>
    </item>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=bf613f06-83f8-4865-be02-03f01c60064f</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,bf613f06-83f8-4865-be02-03f01c60064f.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,bf613f06-83f8-4865-be02-03f01c60064f.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=bf613f06-83f8-4865-be02-03f01c60064f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I am on crusade to get Windows Identity Foundation (WIF) adopted by the Microsoft
.NET community at large. Why? Because maintaining a user store within an application
as is propagated by ASP.NET Membership is just plain stupid these days. Yes, I may
be a little harsh with that judgment, but sparing the rod spoils the child. Applications
should no longer be islands, but should be working together. And if applications such
as Spotify and Flickr can (re)use a user’s identity from Facebook, Twitter, LinkedIn,
and so on, <strong>why can’t yours?</strong></p>
        <p>
          <em>“A thousand mile journey begins with one step” – Lao Tze</em>
        </p>
        <p>
In the past couple of years I’ve been speaking about WIF on many occasions, both at
conference and with individual developers. Across the board I can say that WIF is
largely misunderstood. Hence my first step is to address some of the misconceptions
surrounding WIF, and more in general the concepts underlying WIF. I’ll follow up with
posts showing you (to material on the web) to make it work.
</p>
        <p>
          <strong>Misconception 1: WIF is Microsoft-only and not interoperable.</strong>
          <br />
WIF actually implements the WS-Federation standard. Microsoft is an active participant
in the standards commonly known as the WS-* specifications, a host of web services
specifications for security, transactions, and reliable messaging. The WS-Federation
standard is implemented by many other platforms, and WIF can interoperate with these
just fine.
</p>
        <p>
          <strong>Misconception 2: WIF can only be used to secure web applications, not web
services.</strong>
          <br />
The WS-Federation protocol defines two profiles: Active and Passive. Passive federation
is for browser based applications, because browsers don’t support the full cryptographic
stack required for WS-Federation to work. Active federation is used for web services
and can be used with clients that do support the needed cryptographic capabilities.
I’ll get back to what this all means in another post.
</p>
        <p>
          <strong>Misconception 3: WIF can only be used to secure web services, not web applications.</strong>
          <br />
See misconception #2.
</p>
        <p>
          <strong>Misconception 4: WIF is only for cloud (Azure) applications.</strong>
          <br />
WIF works with any application written in .NET 3.5 and up. You can host that application
anywhere you like, in the cloud or in your own data center. In fact, there is nothing
that prevents you from creating applications with WIF for use in just the local network
and for internal use only.
</p>
        <p>
          <strong>Misconception 5: You can’t do role-based security with WIF.</strong>
          <br />
Quite the opposite is true. You can still do role-based security if you want to, but
you can do much more. The underlying protocol is much more flexible, and you can implement
security checks in your applications based on the information you get about a use
any way you like.
</p>
        <p>
          <strong>Misconception 6: WIF only adds complexity.</strong>
          <br />
It is indeed true that properly connecting a WIF enabled application to a security
token service can be a challenge. You need to get the protocol settings to match and
need certificates for encryption and signing. However, inside your applications WIF
is just as easy as role-based security as you are used to. If you want to do more
elaborate things, things obviously get more complex, but this is true for any type
of security.
</p>
        <p>
          <strong>Misconception 7: To use WIF in an existing application I need to re-architect
the whole application.</strong>
          <br />
WIF extends the IIdentity and IPrincipal interfaces. This means that your existing
application will keep working if you migrate to WIF to get authenticate and authorize
the user. The only thing you need to be aware of is the fact that because you don’t
have a local user directory anymore, you can’t do things for which you require information
about another user. This means you may have to provide a different way to deal with
such scenarios. If you use ASP.NET Profiles for this kind of information, a custom
provider may be all you need. 
</p>
        <img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=bf613f06-83f8-4865-be02-03f01c60064f" />
      </body>
      <title>Common Windows Identity Foundation misconceptions</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,bf613f06-83f8-4865-be02-03f01c60064f.aspx</guid>
      <link>http://michiel.vanotegem.nl/2012/02/09/CommonWindowsIdentityFoundationMisconceptions.aspx</link>
      <pubDate>Thu, 09 Feb 2012 22:26:30 GMT</pubDate>
      <description>&lt;p&gt;
I am on crusade to get Windows Identity Foundation (WIF) adopted by the Microsoft
.NET community at large. Why? Because maintaining a user store within an application
as is propagated by ASP.NET Membership is just plain stupid these days. Yes, I may
be a little harsh with that judgment, but sparing the rod spoils the child. Applications
should no longer be islands, but should be working together. And if applications such
as Spotify and Flickr can (re)use a user’s identity from Facebook, Twitter, LinkedIn,
and so on, &lt;strong&gt;why can’t yours?&lt;/strong&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;“A thousand mile journey begins with one step” – Lao Tze&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
In the past couple of years I’ve been speaking about WIF on many occasions, both at
conference and with individual developers. Across the board I can say that WIF is
largely misunderstood. Hence my first step is to address some of the misconceptions
surrounding WIF, and more in general the concepts underlying WIF. I’ll follow up with
posts showing you (to material on the web) to make it work.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Misconception 1: WIF is Microsoft-only and not interoperable.&lt;/strong&gt;
&lt;br&gt;
WIF actually implements the WS-Federation standard. Microsoft is an active participant
in the standards commonly known as the WS-* specifications, a host of web services
specifications for security, transactions, and reliable messaging. The WS-Federation
standard is implemented by many other platforms, and WIF can interoperate with these
just fine.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Misconception 2: WIF can only be used to secure web applications, not web
services.&lt;/strong&gt;
&lt;br&gt;
The WS-Federation protocol defines two profiles: Active and Passive. Passive federation
is for browser based applications, because browsers don’t support the full cryptographic
stack required for WS-Federation to work. Active federation is used for web services
and can be used with clients that do support the needed cryptographic capabilities.
I’ll get back to what this all means in another post.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Misconception 3: WIF can only be used to secure web services, not web applications.&lt;/strong&gt;
&lt;br&gt;
See misconception #2.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Misconception 4: WIF is only for cloud (Azure) applications.&lt;/strong&gt;
&lt;br&gt;
WIF works with any application written in .NET 3.5 and up. You can host that application
anywhere you like, in the cloud or in your own data center. In fact, there is nothing
that prevents you from creating applications with WIF for use in just the local network
and for internal use only.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Misconception 5: You can’t do role-based security with WIF.&lt;/strong&gt;
&lt;br&gt;
Quite the opposite is true. You can still do role-based security if you want to, but
you can do much more. The underlying protocol is much more flexible, and you can implement
security checks in your applications based on the information you get about a use
any way you like.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Misconception 6: WIF only adds complexity.&lt;/strong&gt;
&lt;br&gt;
It is indeed true that properly connecting a WIF enabled application to a security
token service can be a challenge. You need to get the protocol settings to match and
need certificates for encryption and signing. However, inside your applications WIF
is just as easy as role-based security as you are used to. If you want to do more
elaborate things, things obviously get more complex, but this is true for any type
of security.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Misconception 7: To use WIF in an existing application I need to re-architect
the whole application.&lt;/strong&gt;
&lt;br&gt;
WIF extends the IIdentity and IPrincipal interfaces. This means that your existing
application will keep working if you migrate to WIF to get authenticate and authorize
the user. The only thing you need to be aware of is the fact that because you don’t
have a local user directory anymore, you can’t do things for which you require information
about another user. This means you may have to provide a different way to deal with
such scenarios. If you use ASP.NET Profiles for this kind of information, a custom
provider may be all you need. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=bf613f06-83f8-4865-be02-03f01c60064f" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,bf613f06-83f8-4865-be02-03f01c60064f.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Cloud</category>
      <category>English</category>
      <category>Security</category>
      <category>Windows Identity Foundation</category>
    </item>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=66b72f4a-9925-458e-b87b-6d110a8fe03c</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,66b72f4a-9925-458e-b87b-6d110a8fe03c.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,66b72f4a-9925-458e-b87b-6d110a8fe03c.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=66b72f4a-9925-458e-b87b-6d110a8fe03c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Op 15 februari vanaf 18u15 geeft Beth Massi een gratis Masterclass Visual Studio LightSwitch.
Wees er snel bij, want je kunt je tot 10 februari inschrijven en er is een beperkt
aantal plaatsen. Zie de uitnodiging hieronder voor meer informatie.
</p>
        <iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px" title="Preview" height="120" marginheight="0" src="https://skydrive.live.com/embed?cid=8F0FEC59C78A724A&amp;resid=8F0FEC59C78A724A%21733&amp;authkey=AI-citiqAmG4PEQ" frameborder="0" width="98" marginwidth="0" scrolling="no">
        </iframe>
        <img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=66b72f4a-9925-458e-b87b-6d110a8fe03c" />
      </body>
      <title>Masterclass Visual Studio LightSwitch door Beth Massi op 15 februari 2012</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,66b72f4a-9925-458e-b87b-6d110a8fe03c.aspx</guid>
      <link>http://michiel.vanotegem.nl/2012/02/01/MasterclassVisualStudioLightSwitchDoorBethMassiOp15Februari2012.aspx</link>
      <pubDate>Wed, 01 Feb 2012 13:58:55 GMT</pubDate>
      <description>&lt;p&gt;
Op 15 februari vanaf 18u15 geeft Beth Massi een gratis Masterclass Visual Studio LightSwitch.
Wees er snel bij, want je kunt je tot 10 februari inschrijven en er is een beperkt
aantal plaatsen. Zie de uitnodiging hieronder voor meer informatie.
&lt;/p&gt;
&lt;iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px" title=Preview height=120 marginheight=0 src="https://skydrive.live.com/embed?cid=8F0FEC59C78A724A&amp;amp;resid=8F0FEC59C78A724A%21733&amp;amp;authkey=AI-citiqAmG4PEQ" frameborder=0 width=98 marginwidth=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=66b72f4a-9925-458e-b87b-6d110a8fe03c" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,66b72f4a-9925-458e-b87b-6d110a8fe03c.aspx</comments>
      <category>.NET</category>
      <category>Evenementen</category>
      <category>Nederlands</category>
      <category>Silverlight</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=e9e2de19-cace-4336-bdc7-51eb6cd5dfbd</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,e9e2de19-cace-4336-bdc7-51eb6cd5dfbd.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,e9e2de19-cace-4336-bdc7-51eb6cd5dfbd.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=e9e2de19-cace-4336-bdc7-51eb6cd5dfbd</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.amazon.com/Programming-Amazon-EC2-Jurg-Vliet/dp/1449393683/aspnlcom-20">Programming
Amazon EC2</a> by Jurg van Vliet and Flavia Paganelli is practical in nature and takes
you through all the steps to create and configure accounts, develop applications,
and deploy applications. If you’re new to Amazon EC2 (and related services) this is
definitely a good place to start, because it goes through all the components Amazon
offers, such as S3/Cloudfront and RDS for data storage. It also looks at how you can
setup your application to scale up and down, and ensure your application has excellent
uptime. The book takes you by the hand based on some applications the authors have
created themselves. Although this approach makes the book practical, it sometimes
reads as (irritating) marketing for their applications.
</p>
        <p>
          <a href="http://www.amazon.com/Programming-Amazon-EC2-Jurg-Vliet/dp/1449393683/aspnlcom-20">
            <img border="0" src="http://covers.oreilly.com/images/9781449393687/s.gif" />
          </a>
        </p>
        <img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=e9e2de19-cace-4336-bdc7-51eb6cd5dfbd" />
      </body>
      <title>Book Review: Programming Amazon EC2</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,e9e2de19-cace-4336-bdc7-51eb6cd5dfbd.aspx</guid>
      <link>http://michiel.vanotegem.nl/2011/12/09/BookReviewProgrammingAmazonEC2.aspx</link>
      <pubDate>Fri, 09 Dec 2011 13:47:36 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.amazon.com/Programming-Amazon-EC2-Jurg-Vliet/dp/1449393683/aspnlcom-20"&gt;Programming
Amazon EC2&lt;/a&gt; by Jurg van Vliet and Flavia Paganelli is practical in nature and takes
you through all the steps to create and configure accounts, develop applications,
and deploy applications. If you’re new to Amazon EC2 (and related services) this is
definitely a good place to start, because it goes through all the components Amazon
offers, such as S3/Cloudfront and RDS for data storage. It also looks at how you can
setup your application to scale up and down, and ensure your application has excellent
uptime. The book takes you by the hand based on some applications the authors have
created themselves. Although this approach makes the book practical, it sometimes
reads as (irritating) marketing for their applications.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.amazon.com/Programming-Amazon-EC2-Jurg-Vliet/dp/1449393683/aspnlcom-20"&gt;&lt;img border=0 src="http://covers.oreilly.com/images/9781449393687/s.gif"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=e9e2de19-cace-4336-bdc7-51eb6cd5dfbd" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,e9e2de19-cace-4336-bdc7-51eb6cd5dfbd.aspx</comments>
      <category>Cloud</category>
      <category>Development</category>
      <category>English</category>
      <category>Review</category>
    </item>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=01600cfa-faea-4e54-ba10-acd5c760d277</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,01600cfa-faea-4e54-ba10-acd5c760d277.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,01600cfa-faea-4e54-ba10-acd5c760d277.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=01600cfa-faea-4e54-ba10-acd5c760d277</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Workflow Services in .NET 4 allow you to do long running processes. But when you
do that, there's an interesting question: when a workflow has been suspended, under
which user is the workflow running when it is active again. To answer this question
I created a simple workflow that writes the user in the current thread to a log.
On the initial call, the user making the call was logged (in this case I used Windows
Identity Foundation to authenticate, but this should be the same for all types of
authentication). After a Delay of a minute that user was gone, and instead the user
in the current thread was unauthenticated. This means that any code you call from
the workflow can't rely on Thread.CurrentPrincipal to get the proper authorizations.
You have to save the user, and somehow reinstate principal so it runs under the original
context. Alternatively you can use some form of delegation.
</p>
        <img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=01600cfa-faea-4e54-ba10-acd5c760d277" />
      </body>
      <title>Who is running my Workflow Service?</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,01600cfa-faea-4e54-ba10-acd5c760d277.aspx</guid>
      <link>http://michiel.vanotegem.nl/2011/11/24/WhoIsRunningMyWorkflowService.aspx</link>
      <pubDate>Thu, 24 Nov 2011 13:57:23 GMT</pubDate>
      <description>&lt;p&gt;
Workflow Services in .NET 4 allow you to do long running processes. But when&amp;nbsp;you
do that, there's an interesting question: when a workflow has been suspended, under
which user is the workflow running when it is active again. To answer this question
I created a simple workflow that writes the user in the current thread&amp;nbsp;to a log.
On the initial call, the user making the call was logged (in this case I used Windows
Identity Foundation to authenticate, but this should be the same for all types of
authentication). After a Delay of a minute that user was gone, and instead the user
in the current thread was unauthenticated. This means that any code you call from
the workflow can't rely on Thread.CurrentPrincipal to get the proper authorizations.
You have to save the user, and somehow reinstate principal so it runs under the original
context. Alternatively you can use some form of delegation.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=01600cfa-faea-4e54-ba10-acd5c760d277" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,01600cfa-faea-4e54-ba10-acd5c760d277.aspx</comments>
      <category>.NET</category>
      <category>English</category>
      <category>WCF</category>
      <category>Windows Identity Foundation</category>
      <category>Windows Workflow Foundation</category>
    </item>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=bb390dcb-e2dd-475c-8d2d-e3edd2c9c23f</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,bb390dcb-e2dd-475c-8d2d-e3edd2c9c23f.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,bb390dcb-e2dd-475c-8d2d-e3edd2c9c23f.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=bb390dcb-e2dd-475c-8d2d-e3edd2c9c23f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Working with Windows Idnentity Foundation can be quite a minefield. Solve one issue,
and the next creeps up. Because it's all these little tweaks to make it work, I often
find myself thinking "How did I solve that last time?" One of those issues is the
exception
</p>
        <p>
          <i>
            <font color="#FF0000">Could not establish trust relationship for the SSL/TLS secure
channel with authority 'somesite.runningunder.ssl'</font>
          </i>
        </p>
        <p>
There are two reasons why you can run into this exception, each discussed below.<br /></p>
        <p>
          <b>The certificate isn't trusted and/or the URL doesn't correspond with the URL in
the certificate.</b> If this is the case, you get certificate warnings when you browse
to the service WSDL with a browser. The best way to solve the former is to have your
(development) environment work with certificates it trusts. This means setting up
a Certificate Authority (Active Directory Certificate Services), placing the root
CA certificate in the Trusted Root Certificates of the machine your clients (and services)
run on, issuing the needed certificates from the CA, and placing these where they
are needed. Alternatively, you can just add a single line of code to your client so
it ignores certificate issues before you do any service call:
</p>
        <pre>System.Net.ServicePointManager.ServerCertificateValidationCallback =
    ((sender, certificate, chain, sslPolicyErrors) =&gt; true);</pre>
        <p>
          <font color="#FF0000">
            <b>WARNING! ONLY USE THE ABOVE CODE FOR DEVELOPMENT PURPOSES.
IT IS NOT SECURE.</b>
          </font>
          <br />
        </p>
        <p>
If after you've done the above you still get an exception, the above code is likely
not even being hit. That means you (also) have the problem below.<br /></p>
        <p>
          <b>You've setup identity trust in your client, and the certificate reference is incorrect.</b> This
often happens when you copied some configuration from somewhere, and forgot to change
the corresponding certificate reference. The red stuff in the client configuration
below (which is much longer in a real configuration) is the culprit. It should contain
the encoded certificate.<br /></p>
        <p>
        </p>
        <pre>
          <span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px">&lt;system.serviceModel&gt;
&lt;client&gt; &lt;endpoint address="https://YourServer/Service1.svc" binding="customBinding"
bindingConfiguration="CustomBinding_IService1" contract="ServiceReference1.IService1"
name="Service1Binding"&gt; &lt;identity&gt; &lt;certificate encodedValue="<font color="#FF0000">MIIF5jCCBM6gAwIBAgIKYSt2tQA...</font>"/&gt;
&lt;/identity&gt; &lt;/endpoint&gt; &lt;/client&gt; &lt;/system.serviceModel&gt;</span>
        </pre>
        <p>
        </p>
        <p>
To solve this, you need to get the base64 encoded certificate string, and paste it
in place of what's in there now. To get it you can do the following:
</p>
        <ol>
          <li>
Browse to the endpoint with your browser.</li>
          <li>
View the certificate information.</li>
          <li>
Save the certificate to file.</li>
          <li>
Open the certificate with notepad.</li>
          <li>
Copy the encoded value between the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----
placeholders.<br /></li>
        </ol>
        <img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=bb390dcb-e2dd-475c-8d2d-e3edd2c9c23f" />
      </body>
      <title>Solving: Could not establish trust relationship for the SSL/TLS secure channel ...</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,bb390dcb-e2dd-475c-8d2d-e3edd2c9c23f.aspx</guid>
      <link>http://michiel.vanotegem.nl/2011/11/14/SolvingCouldNotEstablishTrustRelationshipForTheSSLTLSSecureChannel.aspx</link>
      <pubDate>Mon, 14 Nov 2011 11:31:02 GMT</pubDate>
      <description>&lt;p&gt;
Working with Windows Idnentity Foundation can be quite a minefield. Solve one issue,
and the next creeps up. Because it's all these little tweaks to make it work, I often
find myself thinking "How did I solve that last time?" One of those issues is the
exception
&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;&lt;font color="#FF0000"&gt;Could not establish trust relationship for the SSL/TLS secure
channel with authority 'somesite.runningunder.ssl'&lt;/font&gt;&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
There are two reasons why you can run into this exception, each discussed below.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;The certificate isn't trusted and/or the URL doesn't correspond with the URL in
the certificate.&lt;/b&gt; If this is the case, you get certificate warnings when you browse
to the service WSDL with a browser. The best way to solve the former is to have your
(development) environment work with certificates it trusts. This means setting up
a Certificate Authority (Active Directory Certificate Services), placing the root
CA certificate in the Trusted Root Certificates of the machine your clients (and services)
run on, issuing the needed certificates from the CA, and placing these where they
are needed. Alternatively, you can just add a single line of code to your client so
it ignores certificate issues before you do any service call:
&lt;/p&gt;
&lt;pre&gt;System.Net.ServicePointManager.ServerCertificateValidationCallback =
    ((sender, certificate, chain, sslPolicyErrors) =&amp;gt; true);&lt;/pre&gt;
&lt;p&gt;
&lt;font color="#FF0000"&gt;&lt;b&gt;WARNING! ONLY USE THE ABOVE CODE FOR DEVELOPMENT PURPOSES.
IT IS NOT SECURE.&lt;/b&gt;&lt;/font&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
If after you've done the above you still get an exception, the above code is likely
not even being hit. That means you (also) have the problem below.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;You've setup identity trust in your client, and the certificate reference is incorrect.&lt;/b&gt; This
often happens when you copied some configuration from somewhere, and forgot to change
the corresponding certificate reference. The red stuff in the client configuration
below (which is much longer in a real configuration) is the culprit. It should contain
the encoded certificate.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;&amp;lt;system.serviceModel&amp;gt;
&amp;lt;client&amp;gt; &amp;lt;endpoint address="https://YourServer/Service1.svc" binding="customBinding"
bindingConfiguration="CustomBinding_IService1" contract="ServiceReference1.IService1"
name="Service1Binding"&amp;gt; &amp;lt;identity&amp;gt; &amp;lt;certificate encodedValue="&lt;font color="#FF0000"&gt;MIIF5jCCBM6gAwIBAgIKYSt2tQA...&lt;/font&gt;"/&amp;gt;
&amp;lt;/identity&amp;gt; &amp;lt;/endpoint&amp;gt; &amp;lt;/client&amp;gt; &amp;lt;/system.serviceModel&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
To solve this, you need to get the base64 encoded certificate string, and paste it
in place of what's in there now. To get it you can do the following:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Browse to the endpoint with your browser.&lt;/li&gt;
&lt;li&gt;
View the certificate information.&lt;/li&gt;
&lt;li&gt;
Save the certificate to file.&lt;/li&gt;
&lt;li&gt;
Open the certificate with notepad.&lt;/li&gt;
&lt;li&gt;
Copy the encoded value between the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----
placeholders.&lt;br&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=bb390dcb-e2dd-475c-8d2d-e3edd2c9c23f" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,bb390dcb-e2dd-475c-8d2d-e3edd2c9c23f.aspx</comments>
      <category>.NET</category>
      <category>English</category>
      <category>WCF</category>
      <category>Windows Identity Foundation</category>
    </item>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=70fe4e87-1e8a-4a15-9107-97f76b96df92</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,70fe4e87-1e8a-4a15-9107-97f76b96df92.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,70fe4e87-1e8a-4a15-9107-97f76b96df92.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=70fe4e87-1e8a-4a15-9107-97f76b96df92</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been working with WCF for quite a while, and every so often I run into this exception:
</p>
        <p>
ArgumentException: The provided URI scheme 'https' is invalid; expected 'http'.Parameter
name: via
</p>
        <p>
The problem is obvious. You're trying to access a service under HTTPS, but it's being
called with HTTP. Under most bindings you can solve this by adding somehting like
this to the client binding configuration:
</p>
        <pre>&lt;binding name="MyBinding"&gt; 
  &lt;security mode="<span style="BACKGROUND-COLOR: yellow">Transport</span>"&gt;
&lt;transport clientCredentialType="None" /&gt; &lt;message clientCredentialType="None"
negotiateServiceCredential="false" establishSecurityContext="false" /&gt; &lt;/security&gt;
&lt;/binding&gt;</pre>
        <p>
When you use a (custom) ws2007FederationHttp binding, for instance when working
with Windows Identity Foundation, the above won't work. In that case you need to look
in the binding for the &lt;httpTransport&gt; element and replace it with &lt;http<span style="BACKGROUND-COLOR: yellow">s</span>Transport&gt;.
</p>
        <img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=70fe4e87-1e8a-4a15-9107-97f76b96df92" />
      </body>
      <title>Solving: The provided URI scheme 'https' is invalid; expected 'http'.Parameter name: via</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,70fe4e87-1e8a-4a15-9107-97f76b96df92.aspx</guid>
      <link>http://michiel.vanotegem.nl/2011/11/08/SolvingTheProvidedURISchemeHttpsIsInvalidExpectedHttpParameterNameVia.aspx</link>
      <pubDate>Tue, 08 Nov 2011 13:56:13 GMT</pubDate>
      <description>&lt;p&gt;
I've been working with WCF for quite a while, and every so often I run into this exception:
&lt;/p&gt;
&lt;p&gt;
ArgumentException: The provided URI scheme 'https' is invalid; expected 'http'.Parameter
name: via
&lt;/p&gt;
&lt;p&gt;
The problem is obvious. You're trying to access a service under HTTPS, but it's being
called with HTTP. Under most bindings you can solve this by adding somehting like
this to&amp;nbsp;the client&amp;nbsp;binding configuration:
&lt;/p&gt;
&lt;pre&gt;&amp;lt;binding name="MyBinding"&amp;gt; 
  &amp;lt;security mode="&lt;span style="BACKGROUND-COLOR: yellow"&gt;Transport&lt;/span&gt;"&amp;gt;
&amp;lt;transport clientCredentialType="None" /&amp;gt; &amp;lt;message clientCredentialType="None"
negotiateServiceCredential="false" establishSecurityContext="false" /&amp;gt; &amp;lt;/security&amp;gt;
&amp;lt;/binding&amp;gt;&lt;/pre&gt;
&lt;p&gt;
When you use a (custom)&amp;nbsp;ws2007FederationHttp binding, for instance when working
with Windows Identity Foundation, the above won't work. In that case you need to look
in the binding for the &amp;lt;httpTransport&amp;gt; element and replace it with &amp;lt;http&lt;span style="BACKGROUND-COLOR: yellow"&gt;s&lt;/span&gt;Transport&amp;gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=70fe4e87-1e8a-4a15-9107-97f76b96df92" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,70fe4e87-1e8a-4a15-9107-97f76b96df92.aspx</comments>
      <category>.NET</category>
      <category>English</category>
      <category>WCF</category>
      <category>Windows Identity Foundation</category>
    </item>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=7e5086ff-cb3e-4dc9-8570-aa06b0a6ad07</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,7e5086ff-cb3e-4dc9-8570-aa06b0a6ad07.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,7e5086ff-cb3e-4dc9-8570-aa06b0a6ad07.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=7e5086ff-cb3e-4dc9-8570-aa06b0a6ad07</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently I had the pleasure of diving into audit logging. I’m working on a government
project which involves the law making process, so it is imperative that all database
changes are completely traceable. That means that we need to be able to trace <strong>who
made which changes and when</strong>. We’re working with latest and greatest version
of SQL Server (i.e. SQL Server 2008 R2), which has a feature called SQL Audit. Reading
the documentation SQL Audit seemed to do everything we need, except that it doesn’t
know which application user is making the changes. This is logical since it is a web
application and we’re using delegation. For this reason we were already planning to
have the application send along the user id when it does an insert, update or delete,
and we decided to only logically delete a record. So far so good.
</p>
        <p>
When it came to testing, we quickly found that SQL Audit logs the SQL statement making
the change. Sounds right doesn’t it? Well actually it isn’t. LINQ-to-SQL, LINQ-to-Entities
and other O/R Mappers use parameter queries, and in fact if you edit records in the
SQL Management Studio UI, the same is true. The problem is that the <strong>parameters
are not part of the SQL statement being logged!</strong> So we can see which database
user made what kind of change, but not which data was changed, and hence not which
application user made the change either. Back to the drawing board :(.
</p>
        <p>
In reviewing our options, we looked at:
</p>
        <ul>
          <li>
All logging in the O/R Mapper: Not an option, because we need to know what DBA’s do
too. 
</li>
          <li>
SQL Trace: not recommended by Redmond, and it takes a huge performance hit. 
</li>
          <li>
Triggers: in transaction, taking enormous performance hit. 
</li>
          <li>
C2 auditing: tracks all changes, so it gathers huge amounts of data, not easily searchable. 
</li>
          <li>
Change Data Capture: really for BI purposes, deleted after three days, no indication
of the user making the change.</li>
        </ul>
        <p>
All of the above options have some sort of problem associated with it. The conclusion
is that there is no single solution, unless Microsoft fixes the SQL Audit issue (you
can vote on it here: <a href="https://connect.microsoft.com/SQLServer/feedback/details/624935/sql-server-2008-database-audit-on-insert-update-and-delete-actual-sql-and-not-parameter-values">https://connect.microsoft.com/SQLServer/feedback/details/624935/sql-server-2008-database-audit-on-insert-update-and-delete-actual-sql-and-not-parameter-values</a>).
</p>
        <p>
We now do the following:
</p>
        <ol>
          <li>
In the Data Access Layer add the application user that did the insert or update in
an extra field on the table. 
</li>
          <li>
Only do logical deletes (i.e. add a “Deleted” flag to a table). 
</li>
          <li>
Track all changes using Change Data Capture (which uses the transaction log and therefore
has less impact on performance). 
</li>
          <li>
Export CDC data to an “Audit Database” periodically (like using a data warehouse). 
</li>
          <li>
Use SQL Audit for all changes done by a database user other than the DB account used
by the application. 
</li>
          <li>
Export SQL Audit logs to the Audit Database periodically.</li>
        </ol>
        <p>
By cross referencing SQL Audit and CDC data, we can figure out who changed what if
the change was made outside the application. 
<br /></p>
        <img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=7e5086ff-cb3e-4dc9-8570-aa06b0a6ad07" />
      </body>
      <title>Why SQL Audit is insufficient (and what you can do about it)</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,7e5086ff-cb3e-4dc9-8570-aa06b0a6ad07.aspx</guid>
      <link>http://michiel.vanotegem.nl/2011/10/31/WhySQLAuditIsInsufficientAndWhatYouCanDoAboutIt.aspx</link>
      <pubDate>Mon, 31 Oct 2011 16:00:06 GMT</pubDate>
      <description>&lt;p&gt;
Recently I had the pleasure of diving into audit logging. I’m working on a government
project which involves the law making process, so it is imperative that all database
changes are completely traceable. That means that we need to be able to trace &lt;strong&gt;who
made which changes and when&lt;/strong&gt;. We’re working with latest and greatest version
of SQL Server (i.e. SQL Server 2008 R2), which has a feature called SQL Audit. Reading
the documentation SQL Audit seemed to do everything we need, except that it doesn’t
know which application user is making the changes. This is logical since it is a web
application and we’re using delegation. For this reason we were already planning to
have the application send along the user id when it does an insert, update or delete,
and we decided to only logically delete a record. So far so good.
&lt;/p&gt;
&lt;p&gt;
When it came to testing, we quickly found that SQL Audit logs the SQL statement making
the change. Sounds right doesn’t it? Well actually it isn’t. LINQ-to-SQL, LINQ-to-Entities
and other O/R Mappers use parameter queries, and in fact if you edit records in the
SQL Management Studio UI, the same is true. The problem is that the &lt;strong&gt;parameters
are not part of the SQL statement being logged!&lt;/strong&gt; So we can see which database
user made what kind of change, but not which data was changed, and hence not which
application user made the change either. Back to the drawing board :(.
&lt;/p&gt;
&lt;p&gt;
In reviewing our options, we looked at:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
All logging in the O/R Mapper: Not an option, because we need to know what DBA’s do
too. 
&lt;li&gt;
SQL Trace: not recommended by Redmond, and it takes a huge performance hit. 
&lt;li&gt;
Triggers: in transaction, taking enormous performance hit. 
&lt;li&gt;
C2 auditing: tracks all changes, so it gathers huge amounts of data, not easily searchable. 
&lt;li&gt;
Change Data Capture: really for BI purposes, deleted after three days, no indication
of the user making the change.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
All of the above options have some sort of problem associated with it. The conclusion
is that there is no single solution, unless Microsoft fixes the SQL Audit issue (you
can vote on it here: &lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/624935/sql-server-2008-database-audit-on-insert-update-and-delete-actual-sql-and-not-parameter-values"&gt;https://connect.microsoft.com/SQLServer/feedback/details/624935/sql-server-2008-database-audit-on-insert-update-and-delete-actual-sql-and-not-parameter-values&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
We now do the following:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
In the Data Access Layer add the application user that did the insert or update in
an extra field on the table. 
&lt;li&gt;
Only do logical deletes (i.e. add a “Deleted” flag to a table). 
&lt;li&gt;
Track all changes using Change Data Capture (which uses the transaction log and therefore
has less impact on performance). 
&lt;li&gt;
Export CDC data to an “Audit Database” periodically (like using a data warehouse). 
&lt;li&gt;
Use SQL Audit for all changes done by a database user other than the DB account used
by the application. 
&lt;li&gt;
Export SQL Audit logs to the Audit Database periodically.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
By cross referencing SQL Audit and CDC data, we can figure out who changed what if
the change was made outside the application. 
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=7e5086ff-cb3e-4dc9-8570-aa06b0a6ad07" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,7e5086ff-cb3e-4dc9-8570-aa06b0a6ad07.aspx</comments>
      <category>English</category>
      <category>SQL Server</category>
    </item>
    <item>
      <trackback:ping>http://michiel.vanotegem.nl/Trackback.aspx?guid=87dddcc4-0af4-4868-ba80-58fa68c87d55</trackback:ping>
      <pingback:server>http://michiel.vanotegem.nl/pingback.aspx</pingback:server>
      <pingback:target>http://michiel.vanotegem.nl/PermaLink,guid,87dddcc4-0af4-4868-ba80-58fa68c87d55.aspx</pingback:target>
      <dc:creator>Michiel van Otegem</dc:creator>
      <wfw:comment>http://michiel.vanotegem.nl/CommentView,guid,87dddcc4-0af4-4868-ba80-58fa68c87d55.aspx</wfw:comment>
      <wfw:commentRss>http://michiel.vanotegem.nl/SyndicationService.asmx/GetEntryCommentsRss?guid=87dddcc4-0af4-4868-ba80-58fa68c87d55</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just upgraded my blog to the latest version of dasBlog. I also moved to another
hosting provider. All content has been migrated, but there may be links that are not
working on very old posts. I'll check these in the coming days so everything works
as it should. If you happen to run ito problems, let me know.
</p>
        <img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=87dddcc4-0af4-4868-ba80-58fa68c87d55" />
      </body>
      <title>Upgraded!</title>
      <guid isPermaLink="false">http://michiel.vanotegem.nl/PermaLink,guid,87dddcc4-0af4-4868-ba80-58fa68c87d55.aspx</guid>
      <link>http://michiel.vanotegem.nl/2011/06/25/Upgraded.aspx</link>
      <pubDate>Sat, 25 Jun 2011 22:33:48 GMT</pubDate>
      <description>&lt;p&gt;
I just upgraded my blog to the latest version of dasBlog. I also moved to another
hosting provider. All content has been migrated, but there may be links that are not
working on very old posts. I'll check these in the coming days so everything works
as it should. If you happen to run ito problems, let me know.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://michiel.vanotegem.nl/aggbug.ashx?id=87dddcc4-0af4-4868-ba80-58fa68c87d55" /&gt;</description>
      <comments>http://michiel.vanotegem.nl/CommentView,guid,87dddcc4-0af4-4868-ba80-58fa68c87d55.aspx</comments>
      <category>English</category>
    </item>
  </channel>
</rss>
