<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.southworks.net/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.southworks.net/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Matias Woloski's Blog</title>
	
	<link>http://blogs.southworks.net/mwoloski</link>
	<description>my facade</description>
	<pubDate>Wed, 19 Nov 2008 09:38:59 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.southworks.net/mwoloski" type="application/rss+xml" /><item>
		<title>How to decrypt a GenericXmlSecurityToken using Geneva Framework</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/458595441/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/11/19/how-to-decrypt-a-genericxmlsecuritytoken-using-geneva-framework/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 09:21:21 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[Geneva]]></category>

		<category><![CDATA[Identity]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/2008/11/19/how-to-decrypt-a-genericxmlsecuritytoken-using-geneva-framework/</guid>
		<description><![CDATA[&#160;
This took some time and you are lucky if you hit this after a search. This extension method allows you to decrypt a SAML 1.1 security token using Geneva Framework.

public static ClaimsIdentityCollection ToClaimsIdentityCollection(this GenericXmlSecurityToken token, string thumbprintPrivateKey, string thumbprintIssuerPublicKey, TrustVersion trustVersion)
{
    // Decrypt token
    var tokenString = new StringReader(token.TokenXml.OuterXml);
 [...]]]></description>
			<content:encoded><![CDATA[<p>&#160;</p>
<p>This took some time and you are lucky if you hit this after a search. This extension method allows you to decrypt a SAML 1.1 security token using <a href="http://connect.microsoft.com/content/content.aspx?ContentID=10101&amp;SiteID=642">Geneva Framework</a>.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ClaimsIdentityCollection ToClaimsIdentityCollection(<span style="color: #0000ff">this</span> GenericXmlSecurityToken token, <span style="color: #0000ff">string</span> thumbprintPrivateKey, <span style="color: #0000ff">string</span> thumbprintIssuerPublicKey, TrustVersion trustVersion)
{
    <span style="color: #008000">// Decrypt token</span>
    var tokenString = <span style="color: #0000ff">new</span> StringReader(token.TokenXml.OuterXml);
    var reader = XmlReader.Create(tokenString);

    <span style="color: #008000">// Resolver</span>
    X509Certificate2 privateKey = CertificateUtility.GetCertificateByThumbprint(StoreName.My, StoreLocation.LocalMachine, thumbprintPrivateKey);
    X509SecurityToken privateKeyToken = <span style="color: #0000ff">new</span> X509SecurityToken(privateKey);
    X509Certificate2 issuerKey = CertificateUtility.GetCertificateByThumbprint(StoreName.TrustedPeople, StoreLocation.LocalMachine, thumbprintIssuerPublicKey);
    X509SecurityToken issuerKeyToken = <span style="color: #0000ff">new</span> X509SecurityToken(issuerKey);
    List&lt;SecurityToken&gt; tokens = <span style="color: #0000ff">new</span> List&lt;SecurityToken&gt;();
    tokens.Add(privateKeyToken);
    tokens.Add(issuerKeyToken);
    SecurityTokenResolver outOfBandTokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(<span style="color: #0000ff">new</span> ReadOnlyCollection&lt;SecurityToken&gt;(tokens), <span style="color: #0000ff">false</span>);

    var samlHandler = SecurityTokenHandlerCollection.DefaultHandlers.SingleOrDefault(handler =&gt; handler <span style="color: #0000ff">is</span> Saml11SecurityTokenHandler) <span style="color: #0000ff">as</span> Saml11SecurityTokenHandler;
    samlHandler.SamlSecurityTokenRequirement.IssuerTokenResolver = outOfBandTokenResolver;
    EncryptedSecurityTokenHandler h = <span style="color: #0000ff">new</span> EncryptedSecurityTokenHandler(outOfBandTokenResolver, <span style="color: #0000ff">new</span> SecurityTokenHandlerCollection(<span style="color: #0000ff">new</span> SecurityTokenHandler[] { samlHandler }));
    var serializer2 = <span style="color: #0000ff">new</span> SecurityTokenSerializerAdapter(
        <span style="color: #0000ff">new</span> SecurityTokenHandlerCollection(<span style="color: #0000ff">new</span> SecurityTokenHandler[] { h }),
        SecurityVersion.WSSecurity11,
        trustVersion,
        trustVersion == TrustVersion.WSTrust13 ? SecureConversationVersion.WSSecureConversation13 : SecureConversationVersion.WSSecureConversationFeb2005,
        <span style="color: #0000ff">false</span>,
        <span style="color: #0000ff">null</span>,
        <span style="color: #0000ff">null</span>,
        <span style="color: #0000ff">null</span>);
    var samlSecurityToken = serializer2.ReadToken(reader, outOfBandTokenResolver);

    samlHandler.SamlSecurityTokenRequirement.IssuerNameRegistry = <span style="color: #0000ff">new</span> NullIssuerNameRegistry();

    var handlers = <span style="color: #0000ff">new</span> SecurityTokenHandlerCollection(<span style="color: #0000ff">new</span> SecurityTokenHandler[] { samlHandler });
    var claims = handlers.ValidateToken(samlSecurityToken);

    <span style="color: #0000ff">return</span> claims;
}</pre>
</div>
<p>The way to use it:</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace">var token = GetTokenFromSomewhere();
token.ToClaimsIdentityCollection( <span style="color: #006080">&quot;thmbprint of the cert used to decrypt the token&quot;</span>,
                                  <span style="color: #006080">&quot;thmbprint of the cert used to check the signature of the issuer&quot;</span>,
                                  TrustVersion.WSTrust13 or TrustVersion.WSTrustFeb2005 );</pre>
</div>
<p>Download it from <a href="http://snipurl.com/5xnty">here</a></p>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/458595441" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/11/19/how-to-decrypt-a-genericxmlsecuritytoken-using-geneva-framework/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F11%2F19%2Fhow-to-decrypt-a-genericxmlsecuritytoken-using-geneva-framework%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/11/19/how-to-decrypt-a-genericxmlsecuritytoken-using-geneva-framework/</feedburner:origLink></item>
		<item>
		<title>Windows Azure @ PDC Buenos Aires</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/457159703/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/11/18/windows-azure-pdc-buenos-aires/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 04:41:56 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[Azure]]></category>

		<category><![CDATA[PDC08]]></category>

		<category><![CDATA[Presentation]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/2008/11/18/windows-azure-pdc-buenos-aires/</guid>
		<description><![CDATA[It&#8217;s been two weeks already that we&#8217;ve got back from LA after attending PDC. Lots of things announced there.
Microsoft Argentina organized the local-mini version of PDC. I will be there showing Windows Azure with Edgardo.
 
The talk will be mainly demos (as usual  and explain some concepts around Windows Azure.
You can register here (it [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been two weeks already that we&#8217;ve got back from LA after attending PDC. Lots of things announced there.</p>
<p>Microsoft Argentina organized the local-mini version of PDC. I will be there showing Windows Azure with <a href="http://blogs.southworks.net/erossetto">Edgardo</a>.</p>
<p><a href="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewriterwindowsazurepdcbuenosaires-9e0eimage-4.png"><img height="406" alt="image" src="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewriterwindowsazurepdcbuenosaires-9e0eimage-thumb-1.png" width="640" border="0" /></a> </p>
<p>The talk will be mainly demos (as usual <img src='http://blogs.southworks.net/mwoloski/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> and explain some concepts around Windows Azure.</p>
<p>You can register here (it seems it&#8217;s all booked though): <a title="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032394696&amp;Culture=es-AR" href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032394696&amp;Culture=es-AR">http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032394696&amp;Culture=es-AR</a></p>
<p>Other <em><a href="http://www.southworks.net">southies</a> </em>will be presenting as well at this event: </p>
<ul>
<li><a href="http://blogs.southworks.net/msalias">Martin Salias</a> will be talking about the future of the languages (F# and C#) </li>
<li><a href="http://blogs.southworks.net/parancibia">Paulo Arancibia</a> and <a href="http://blogs.southworks.net/jdominguez">Julian Dominguez</a> will be showing how to develop data driven apps using the new DataGrid and Ribbon controls of WPF.</li>
</ul>
<p>See you there&#8230;</p>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/457159703" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/11/18/windows-azure-pdc-buenos-aires/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F11%2F18%2Fwindows-azure-pdc-buenos-aires%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/11/18/windows-azure-pdc-buenos-aires/</feedburner:origLink></item>
		<item>
		<title>Azure Services Platform - Passive Federation &amp; Access Control #2</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/447506572/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/11/09/azure-services-platform-passive-federation-access-control-2/#comments</comments>
		<pubDate>Sun, 09 Nov 2008 16:19:50 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[Azure]]></category>

		<category><![CDATA[Cloud Computing]]></category>

		<category><![CDATA[Federation]]></category>

		<category><![CDATA[Geneva]]></category>

		<category><![CDATA[Identity Management]]></category>

		<category><![CDATA[LiveID]]></category>

		<category><![CDATA[PDC08]]></category>

		<category><![CDATA[Zermatt]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/2008/11/09/azure-services-platform-passive-federation-access-control-2/</guid>
		<description><![CDATA[
In the previous post I introduced a scenario where you can use .NET Services Access Control and Windows LiveID to delegate authentication and authorization. In this post we will go through the different pieces needed in the application to perform authorization checks. First thing will be configure the passive federation using Geneva on the application [...]]]></description>
			<content:encoded><![CDATA[</p>
<p>In the <a href="http://blogs.southworks.net/mwoloski/2008/11/07/azure-services-platform-passive-federation-access-control-1/">previous post</a> I introduced a scenario where you can use .NET Services Access Control and Windows LiveID to delegate authentication and authorization. In this post we will go through the different pieces needed in the application to perform authorization checks. First thing will be configure the passive federation using Geneva on the application and later we will create an ASP.NET MVC action filter to perform the access check against the incoming claims. </p>
<p><strong>Note</strong>: all the code showed here is using Microsoft Identity Framework &quot;Zermatt&quot; Beta 1. The new Geneva Framework might have some changes.</p>
<h3>Configuring passive federation on the website</h3>
<p>Configure passive federation on the website is about defining which SAML token version we will accept and the certificate we will use to decrypt the incoming token. The following configuration uses Zermatt Beta 1, so this probably changes on Geneva.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">&lt;</span><span style="color: #800000">microsoft.identityModel</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">tokenHandlers</span><span style="color: #0000ff">&gt;</span>
      <span style="color: #0000ff">&lt;</span><span style="color: #800000">remove</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">=&quot;Microsoft.IdentityModel.Tokens.Saml11.Saml11TokenHandler, Microsoft.IdentityModel, Version=0.4.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&quot;</span> <span style="color: #0000ff">/&gt;</span>
      <span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">=&quot;Microsoft.IdentityModel.Tokens.Saml11.Saml11TokenHandler, Microsoft.IdentityModel, Version=0.4.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&quot;</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">samlSecurityTokenRequirement</span><span style="color: #0000ff">&gt;</span>
          <span style="color: #0000ff">&lt;</span><span style="color: #800000">allowedAudienceUris</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">value</span><span style="color: #0000ff">=&quot;http://localhost/YourApp/&quot;</span> <span style="color: #0000ff">/&gt;</span>
          <span style="color: #0000ff">&lt;/</span><span style="color: #800000">allowedAudienceUris</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;/</span><span style="color: #800000">samlSecurityTokenRequirement</span><span style="color: #0000ff">&gt;</span>
      <span style="color: #0000ff">&lt;/</span><span style="color: #800000">add</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">tokenHandlers</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">federatedAuthentication</span> <span style="color: #ff0000">enabled</span><span style="color: #0000ff">=&quot;true&quot;</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">federatedAuthentication</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">serviceCertificate</span><span style="color: #0000ff">&gt;</span>
      <span style="color: #0000ff">&lt;</span><span style="color: #800000">certificateReference</span> <span style="color: #ff0000">findValue</span><span style="color: #0000ff">=&quot;01 20 &#8230;&quot;</span> <span style="color: #ff0000">storeLocation</span><span style="color: #0000ff">=&quot;LocalMachine&quot;</span> <span style="color: #ff0000">storeName</span><span style="color: #0000ff">=&quot;My&quot;</span> <span style="color: #ff0000">x509FindType</span><span style="color: #0000ff">=&quot;FindByThumbprint&quot;</span> <span style="color: #0000ff">/&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">serviceCertificate</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">microsoft.identityModel</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>When the user click on the sign in button, the link will point to to the .NET Services Access Control passive STS url. The following method uses Geneva to generate this WS-Federation url.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">string</span> GetFederationUrl(<span style="color: #0000ff">string</span> realm, <span style="color: #0000ff">string</span> issuer, <span style="color: #0000ff">string</span> homeRealm, <span style="color: #0000ff">string</span> returnUrl)
{
    FederatedAuthenticationModule fam = <span style="color: #0000ff">new</span> FederatedAuthenticationModule();
    fam.Realm = realm;
    fam.Issuer = issuer;
    fam.Reply = returnUrl;
    SignInRequestMessage signInMsg = fam.CreateSignInRequest();
    signInMsg.Parameters.Add(<span style="color: #006080">&quot;whr&quot;</span>, homeRealm);
    <span style="color: #0000ff">string</span> url = signInMsg.WriteQueryString();
    <span style="color: #0000ff">return</span> url;
}</pre>
</div>
<p>The following code and configuration will give you an idea of the url that is being built. Pay attention to this url because a small change might break the whole thing.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">string</span> url = GetFederationUrl(ConfigurationManager.AppSettings[<span style="color: #006080">&quot;AccessControlRealm&quot;</span>],
                            ConfigurationManager.AppSettings[<span style="color: #006080">&quot;AccessControlIssuer&quot;</span>],
                            ConfigurationManager.AppSettings[<span style="color: #006080">&quot;AccessControlHomeRealm&quot;</span>],
                            replyTo);</pre>
</div>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #008000">&lt;!&#8211; Windows Azure Federation &#8211;&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">key</span><span style="color: #0000ff">=&quot;AccessControlRealm&quot;</span> <span style="color: #ff0000">value</span><span style="color: #0000ff">=&quot;http://localhost/YourApp/&quot;</span><span style="color: #0000ff">/&gt;</span> <span style="color: #008000">&lt;!&#8211; should match to a scope &#8211;&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">key</span><span style="color: #0000ff">=&quot;AccessControlIssuer&quot;</span> <span style="color: #ff0000">value</span><span style="color: #0000ff">=&quot;https://accesscontrol.windows.net/passivests/yoursolution/LiveFederation.aspx&quot;</span><span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">key</span><span style="color: #0000ff">=&quot;AccessControlDefaultReply&quot;</span> <span style="color: #ff0000">value</span><span style="color: #0000ff">=&quot;http://localhost/YourApp&quot;</span> <span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">key</span><span style="color: #0000ff">=&quot;AccessControlHomeRealm&quot;</span> <span style="color: #ff0000">value</span><span style="color: #0000ff">=&quot;http://login.live.com&quot;</span> <span style="color: #0000ff">/&gt;</span></pre>
</div>
<p>The AccessControlRealm config is important because it will match the scope on your solution. You will have to configure the scope to encrypt with the public key of your website certificate and create the claim mappings from Windows LiveID to your well known claims. If you don&#8217;t have the scope created or configured to output at least one claim you will get a 403 Forbidden on the .NET Services Access Control STS.</p>
<p><a href="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewriterazureservicesplatformpassivefederationac-bdb7image-4.png"><img height="424" alt="image" src="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewriterazureservicesplatformpassivefederationac-bdb7image-thumb-1.png" width="640" border="0" /></a> </p>
<h3>Performing access check in the web site</h3>
<p>Now that we have everything configured and the token should be coming back to our website, it&#8217;s time to do the access check. By using Geneva, the token will be transformed to a Principal object and it will be accessed through the ClaimsPrincipal static class. On the other hand, ASP.NET MVC allow us to plug into the action execution pipeline and get access to the context data like route values. The following code shows an ActionFilterAttribute that will grab the claims from the the Geneva ClaimsPrincipal and will call a strategy class that will perform the access check. If the access check is not successful, the filter will render a NotAuthorized view.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">namespace</span> YourApp.Identity
{
    <span style="color: #0000ff">using</span> System;
    &#8230;

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ClaimAuthorizationRouteFilterAttribute : ActionFilterAttribute
    {
        <span style="color: #0000ff">public</span> ClaimAuthorizationRouteFilterAttribute(<span style="color: #0000ff">string</span>[] operations)
        {
            <span style="color: #0000ff">this</span>.Operations = operations;
        }

        <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span>[] Operations { get; set; }

        <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnActionExecuting(ActionExecutingContext context)
        {
            var identity = ClaimsPrincipal.Current.Identity <span style="color: #0000ff">as</span> IClaimsIdentity;
            var claims = identity.Claims.ToArray();
            var routeData = context.RouteData.Values.ToArray();
            var strategy = CreateAuthorizationStrategy();
            var executionContext = <span style="color: #0000ff">new</span> ExecutionContext()
            {
                ClaimsNeeded = Operations,
                OperationContextData = routeData,
            };

            <span style="color: #0000ff">if</span> (!strategy.IsAuthorizedFor(executionContext, claims))
            {
                context.Result = <span style="color: #0000ff">new</span> ViewResult
                {
                    ViewName = <span style="color: #006080">&quot;NotAuthorized&quot;</span>
                };
            }

            <span style="color: #0000ff">base</span>.OnActionExecuting(context);
        }

    }
}</pre>
</div>
<p>Finally, the following code shows an implemented strategy for a multi tenant application that manage projects.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">namespace</span> YourApp.Identity
{
    <span style="color: #0000ff">using</span> System.Linq;
    <span style="color: #0000ff">using</span> System;

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> StandardAuthorizationStrategy : IAuthorizationStrategy
    {
        <span style="color: #0000ff">private</span> <span style="color: #0000ff">const</span> <span style="color: #0000ff">string</span> ProjectClaimType = <span style="color: #006080">&quot;urn:Project&quot;</span>;
        <span style="color: #0000ff">private</span> <span style="color: #0000ff">const</span> <span style="color: #0000ff">string</span> TenantClaimType = <span style="color: #006080">&quot;urn:Tenant&quot;</span>;
        <span style="color: #0000ff">private</span> <span style="color: #0000ff">const</span> <span style="color: #0000ff">string</span> OperationClaimType = <span style="color: #006080">&quot;urn:Operation&quot;</span>;

        <span style="color: #0000ff">public</span> <span style="color: #0000ff">bool</span> IsAuthorizedFor(ExecutionContext context, Microsoft.IdentityModel.Claims.Claim[] claims)
        {
            <span style="color: #0000ff">bool</span> authorized = <span style="color: #0000ff">true</span>;
            var tenantClaim = claims.SingleOrDefault(c =&gt; c.ClaimType == TenantClaimType);
            var operationClaims = claims.Where(c =&gt; c.ClaimType == OperationClaimType);
            var projectClaims = claims.Where(c =&gt; c.ClaimType == ProjectClaimType);
        var tenant = context.OperationContextData[<span style="color: #006080">&quot;Tenant&quot;</span>].ToString();
        var project = context.OperationContextData[<span style="color: #006080">&quot;Project&quot;</span>].ToString();

            <span style="color: #0000ff">if</span> (!<span style="color: #0000ff">string</span>.IsNullOrEmpty(tenant))
            {
                authorized &amp;= tenantClaim.Value.Equals(<span style="color: #006080">&quot;*&quot;</span>, StringComparison.OrdinalIgnoreCase) ||
                              tenantClaim.Value.Equals(tenant, StringComparison.OrdinalIgnoreCase);
            }

            <span style="color: #0000ff">if</span> (!<span style="color: #0000ff">string</span>.IsNullOrEmpty(project))
            {
                authorized &amp;= projectClaims.Where( p =&gt; p.Value.Equals(<span style="color: #006080">&quot;*&quot;</span>, StringComparison.OrdinalIgnoreCase)).Count() &gt; 0 ||
                              projectClaims.Where( p =&gt; p.Value.Equals(project, StringComparison.OrdinalIgnoreCase)).Count() &gt; 0;
            }

            <span style="color: #0000ff">if</span> (context.Operations != <span style="color: #0000ff">null</span>)
            {
                <span style="color: #0000ff">bool</span> temp = <span style="color: #0000ff">true</span>;
                <span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">string</span> op <span style="color: #0000ff">in</span> context.ClaimsNeeded)
                {
                    temp &amp;= operationClaims.Where(o =&gt; o.Value.Equals(op, StringComparison.OrdinalIgnoreCase)).Count() &gt; 0 ||
                            operationClaims.Where(o =&gt; o.Value.Equals(<span style="color: #006080">&quot;*&quot;</span>, StringComparison.OrdinalIgnoreCase)).Count() &gt; 0;
                }
                authorized &amp;= temp;
            }

            <span style="color: #0000ff">return</span> authorized;
        }
    }
}</pre>
</div>
<p>The only thing left is to put an attribute above the action. The following attribute specifies that the New action will be executed if the incoming token contains the following &quot;urn:Operation&quot; claims.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ProjectsController : Controller
{

        [ClaimAuthorizationRouteFilter(<span style="color: #0000ff">new</span> <span style="color: #0000ff">string</span>[] {
                                            <span style="color: #006080">&quot;AddUser&quot;</span>,
                                            <span style="color: #006080">&quot;AddUsersToProject&quot;</span>,
                                            <span style="color: #006080">&quot;CreateProject&quot;</span> })]
        <span style="color: #0000ff">public</span> ActionResult New() {
        &#8230;.

    }

    &#8230;

}</pre>
</div>
<p>So if a user browses to: http://yourapp/Contoso/Projecsts/New, the filter will call the strategy that will check:</p>
<ul>
<li>if the user contains a tenant claim with the value &quot;Contoso&quot; (taken from the route data) </li>
<li>if the user contains three operation claims: AddUser, AddUsersToProject and CreateProject </li>
</ul>
<p>And if a user browses to: http://yourapp/Contoso/Projecsts/some-project/Edit, the filter will call the strategy that will check:</p>
<ul>
<li>if the user contains a &quot;tenant&quot; claim with the value &quot;Contoso&quot; (taken from the route data) </li>
<li>if the user contains the &quot;operation&quot; claims specified in the Edit action </li>
<li>if the user contains a &quot;project&quot; claim with the value &quot;some-project&quot; </li>
</ul>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/447506572" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/11/09/azure-services-platform-passive-federation-access-control-2/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F11%2F09%2Fazure-services-platform-passive-federation-access-control-2%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/11/09/azure-services-platform-passive-federation-access-control-2/</feedburner:origLink></item>
		<item>
		<title>Azure Services Platform - Passive Federation &amp; Access Control #1</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/444564679/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/11/07/azure-services-platform-passive-federation-access-control-1/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 07:45:05 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[Azure]]></category>

		<category><![CDATA[Federation]]></category>

		<category><![CDATA[Geneva]]></category>

		<category><![CDATA[Identity Management]]></category>

		<category><![CDATA[LiveID]]></category>

		<category><![CDATA[PDC08]]></category>

		<category><![CDATA[Zermatt]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/2008/11/07/azure-services-platform-passive-federation-access-control-1/</guid>
		<description><![CDATA[
The last couple of months together with other people at Southworks we&#8217;ve been working with the DPE team on samples, demos, hands on labs for PDC all related to the cloud computing services Microsoft announced at PDC, the Azure Services Platform.&#160; 

During the week, I attended Kim Cameron&#8217;s and Vittorio Bertocci session where they talked [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewritercloudcomputing-d6a0image-5.png"><img height="34" alt="image" src="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewritercloudcomputing-d6a0image-thumb.png" width="237" align="right" border="0" /></a>
<p>The last couple of months together with other people at <a href="http://www.southworks.net">Southworks</a> we&#8217;ve been working with the DPE team on samples, demos, hands on labs for PDC all related to the cloud computing services Microsoft announced at PDC, the Azure Services Platform.&#160; </p>
</p>
<p>During the week, I attended <a href="http://www.identityblog.com/">Kim Cameron</a>&#8217;s and <a href="http:/blogs.msdn.com/vibro.net">Vittorio Bertocci</a> session where they talked about identity federation and claim based architecture using &quot;Geneva&quot; Server, Microsoft Federation Gateway, &quot;Geneva&quot; Framework (previously known as Zermatt) and the .NET Services Access Control. I enjoyed watching Vittorio during the session.&#160; </p>
<p>Other interesting things we did in the identity arena with <a href="http://dunnry.com">Ryan Dunn</a> is use the .NET Services Access Control and Windows Live ID to delegate authentication and authorization to the cloud. In this post I will introduce the scenario where you can federate your application against .NET Services Access Control which indeed federates against Windows LiveID. This will allow users of your application to log in to your application using their Windows LiveID account and then use .NET Services Access Control to transform the email claim to a set of claims to perform authorization access checks.</p>
<h3><strong>Identity + Access Control</strong> using <strong>Windows Live ID + .NET Services Access Control</strong></h3>
<p>Windows Live ID can authenticate users of your web site and then use .NET Services Access Control to map claims between the Live ID (email) and some other claim (like role, operation, task). The image below shows a claim mapping that you would create in your .NET Services account.</p>
<p><a href="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewritercloudcomputing-d6a0image-7.png"><img height="219" alt="image" src="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewritercloudcomputing-d6a0image-thumb-2.png" width="569" border="0" /></a> </p>
<p>The output claims could be used later in the application to perform access check against resources or modify the UI according to the incoming claims. The flow is governed by the WS-Federation protocol as shown below:</p>
<p>&#160;</p>
<p><a href="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewritercloudcomputing-d6a0image-13.png"><img height="480" alt="image" src="http://blogs.southworks.net/mwoloski/files/2008/11/windowslivewritercloudcomputing-d6a0image-thumb-5.png" width="590" border="0" /></a> </p>
<p>In a nutshell, the browser will click on the Sign In link on the website and it will be redirected to the token issuer, in this case the .NET Services Access Control passive STS. The home realm on the url will be login.live.com and the .NET Services STS trust on Windows LiveID tokens. The user will log in on Windows LiveID and it will send the token back to the .NET Services STS. Finally the claim mapping will occur and the token will come back to the website with the authorization claims.</p>
<p>In the following post I will show how to configure your application to read the incoming token claims and do access check over page urls.</p>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/444564679" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/11/07/azure-services-platform-passive-federation-access-control-1/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F11%2F07%2Fazure-services-platform-passive-federation-access-control-1%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/11/07/azure-services-platform-passive-federation-access-control-1/</feedburner:origLink></item>
		<item>
		<title>Azure Services Kit available</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/436334909/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/10/30/azure-services-kit-available/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 10:38:30 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[Azure]]></category>

		<category><![CDATA[Cloud Computing]]></category>

		<category><![CDATA[Hands on Labs]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/2008/10/30/azure-services-kit-available/</guid>
		<description><![CDATA[
The work we did through the last couple of months is materialized now. James Conard and the DPE team (Nigel Watling, Ryan Dunn, Vittorio Bertocci, Drew Robbins, et al) were able to hit the road before anyone else at Microsoft by releasing the Azure Services Training Kit. 
I was walking through the Hands On Labs [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogs.southworks.net/mwoloski/files/2008/10/windowslivewriterazureserviceskitavailable-e099pa280103-50percent.jpg"><img height="258" alt="PA280103_50percent" src="http://blogs.southworks.net/mwoloski/files/2008/10/windowslivewriterazureserviceskitavailable-e099pa280103-50percent-thumb.jpg" width="337" align="right" border="0" /></a>
<p>The work we did through the last couple of months is materialized now. <a href="http://blogs.msdn.com/jamescon/">James Conard</a> and the DPE team (Nigel Watling, Ryan Dunn, Vittorio Bertocci, Drew Robbins, et al) were able to hit the road before anyone else at Microsoft by releasing the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=413e88f8-5966-4a83-b309-53b7b77edf78&amp;DisplayLang=en">Azure Services Training Kit</a>. </p>
<p>I was walking through the Hands On Labs lounge today, watching at people doing lines to do the labs.</p>
<p>The kit includes labs on:</p>
<ul>
<li>SQL Data Services</li>
<li>Windows Azure</li>
<li>.NET Services Service Bus</li>
<li>.NET Services Access Control</li>
<li>.NET Services Workflow</li>
</ul>
<p>You will need an invitation code, but you will be able to read the document and code to get lots of information.</p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=413e88f8-5966-4a83-b309-53b7b77edf78&amp;DisplayLang=en">Download it now</a></p>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/436334909" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/10/30/azure-services-kit-available/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F10%2F30%2Fazure-services-kit-available%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/10/30/azure-services-kit-available/</feedburner:origLink></item>
		<item>
		<title>Performance back to back at CodeCamp 08</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/410716061/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/10/03/performance-back-to-back-at-codecamp-08/#comments</comments>
		<pubDate>Fri, 03 Oct 2008 23:34:40 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[CodeCamp08]]></category>

		<category><![CDATA[High Performance WebSites]]></category>

		<category><![CDATA[Load Testing]]></category>

		<category><![CDATA[Performance]]></category>

		<category><![CDATA[Presentation]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/?p=345</guid>
		<description><![CDATA[Tomorrow I will be at CodeCamp talking about performance on two different presentations. One of them is about the front end performance of web applications (a similar talk to the one presented at MIX last june), but this time I will do it with Paulo Arancibia.
In the other presentation I will join Federico Boerr and [...]]]></description>
			<content:encoded><![CDATA[<p>Tomorrow I will be at <a href="http://www.microsoft.com/Argentina/CodeCamp/">CodeCamp</a> talking about performance on two different presentations. One of them is a<img style="margin: 10px" src="http://blogs.southworks.net/mwoloski/files/2008/10/image.png" border="0" alt="image" width="244" height="48" align="right" />bout the front end performance of web applications (a similar talk to the one <a href="http://blogs.southworks.net/mwoloski/2008/06/10/mix-essentials-high-performance-web-sites-with-aspnet/">presented at MIX last june</a>), but this time I will do it with <a href="http://blogs.southworks.net/parancibia">Paulo Arancibia</a>.</p>
<p>In the other presentation I will join <a href="http://blogs.southworks.net/fboerr">Federico Boerr</a> and together we will try to demystified performance and load testing based on real world experience.</p>
<p>Since the audience will be half students and half professional developers, we decided to do both presentations in a extremely pragmatic fashion, showing tips &amp; tricks. The deck of one of the presentations has just 3 slides! I will post them after the event, but here you have a preview:</p>
<table border="0" cellspacing="0" cellpadding="2" width="400">
<tbody>
<tr>
<td width="200" valign="top"><a href="http://blogs.southworks.net/mwoloski/files/2008/10/image1.png"><img src="http://blogs.southworks.net/mwoloski/files/2008/10/image-thumb.png" border="0" alt="image" width="324" height="244" /></a></td>
<td width="200" valign="top"><a href="http://blogs.southworks.net/mwoloski/files/2008/10/image2.png"><img src="http://blogs.southworks.net/mwoloski/files/2008/10/image-thumb1.png" border="0" alt="image" width="324" height="239" /></a></td>
</tr>
<tr>
<td width="200" valign="top"><strong>Presentation (3 - 4 PM)</strong>: 14 rules for web app performance improvement</td>
<td width="200" valign="top"><strong>Presentation (4:15 - 5:15 PM)</strong>: How To: Perf and Load Testing</td>
</tr>
</tbody>
</table>
<p> </p>
<p>On the other hand, <a href="http://www.southworks.net">Southworks</a> is one of the sponsors of the event and several other <em><strong>southies</strong></em> will be presenting as well (actually 7 presentations, wow!):</p>
<ul>
<li><a href="http://blogs.southworks.net/jhalife/">Johnny</a> and <a href="http://blogs.southworks.net/pdamiani">Lito</a> about the Microsoft Data platform with SQL (they will do the <a href="http://blogs.msdn.com/zowens/archive/2008/06/05/teched-2008-developers-a-mi-gente-de-southworks-es.aspx">demo that Southworks prepared for BillG KeyNote at TechEd Orlando 2008</a>)</li>
<li><a href="http://blogs.southworks.net/aortega">Beto</a> y <a href="http://blogs.southworks.net/ejadib">Ezequiel Jadib</a> will do a dev + IT talk on application health monitoring</li>
<li><a href="http://blogs.southworks.net/msalias">Martin Salias</a> on his usual and great dynamic languages talk (Python on .NET)</li>
<li><a href="http://msmvps.com/blogs/lopez/default.aspx">Angel Lopez</a> is covering one of the speakers and will do one of our favorites topics: MS Robotics Studio</li>
<li><a href="http://blogs.southworks.net/aalvarez">Augusto Alvarez</a> on IIS7</li>
</ul>
<p><a href="http://www.southworks.net">Southworks</a> will have a booth as well, so feel free to stop by for some geek talks!</p>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/410716061" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/10/03/performance-back-to-back-at-codecamp-08/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F10%2F03%2Fperformance-back-to-back-at-codecamp-08%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/10/03/performance-back-to-back-at-codecamp-08/</feedburner:origLink></item>
		<item>
		<title>Thesis - Software as a Service</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/405902689/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/09/28/thesis-software-as-a-service/#comments</comments>
		<pubDate>Mon, 29 Sep 2008 02:04:17 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[Cloud Computing]]></category>

		<category><![CDATA[SaaS]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/?p=339</guid>
		<description><![CDATA[
My interest in Software as a Service (SaaS) born during a trip to Microsoft in 2006. Looking for an interesting topic to elaborate on my graduate thesis, I started digging on different areas and asking different colleagues and friends. Initially, influenced by the work of Arvindra Sehmi, I got interested in agent programming (BDI agents, [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin: 0px 0px 0px 20px" src="http://blogs.southworks.net/mwoloski/files/2008/09/image1.png" border="0" alt="cloud computing" width="260" height="178" align="right" /></p>
<p>My interest in Software as a Service (SaaS) born during a trip to Microsoft in 2006. Looking for an interesting topic to elaborate on my graduate thesis, I started digging on different areas and asking different colleagues and friends. Initially, influenced by the work of <a href="http://www.thearchitectexchange.com/asehmi/">Arvindra Sehmi</a>, I got interested in agent programming (<a href="http://en.wikipedia.org/wiki/BDI_software_agent">BDI agents</a>, <a href="http://en.wikipedia.org/wiki/Multi-agent_system">multi-agents systems</a>, etc). Later, <a href="http://blogs.msdn.com/eugeniop">Eugenio Pace</a>, a mentor and friend, commented me about an emerging model of software distribution. After a couple of months, Alejandro Jack (mentor and friend also), contacted me with <a href="http://blogs.msdn.com/jdevados/">John DeVadoos</a> (former director of the <a href="http://msdn.microsoft.com/architecture">Architecture Strategy Team</a> at Microsoft, now leading the <a href="http://msdn.microsoft.com/practices">patterns &amp; practices</a> team). This group was formed by <a href="http://blogs.msdn.com/gianpolo">Gianpaolo Carraro</a> and <a href="http://blogs.msdn.com/fred_chong">Fred Chong</a> initially and last year Eugenio joined them and Fred left. Their daily job consists of researching the Software as a Service model from the architectural point of view. As part of this challenge, the group establishes relationships with clients interested in the model and with product teams looking for feedback to shorten the gap <a href="http://blogs.southworks.net/mwoloski/files/2008/09/redmond-northwind-hosting-042.jpg"><img style="margin: 10px 0px 5px 10px" src="http://blogs.southworks.net/mwoloski/files/2008/09/redmond-northwind-hosting-042-thumb.jpg" border="0" alt="Redmond Northwind Hosting 042" width="260" height="200" align="right" /></a>on the platform. The group also publishes a number of <a href="http://msdn.microsoft.com/en-us/architecture/aa699384.aspx">papers</a> and <a href="http://www.codeplex.com/LitwareHr">proof of concepts</a> using Microsoft technologies. I did a good connection with them and finally decided to pick Software as a Service as the topic for my thesis.</p>
<p>Throughout the last two years I&#8217;ve been collaborating with this group writing proof of concepts, preparing and delivering workshops. On the right, it&#8217;s me working with Eugenio (on the left) at building 20 one year ago (Gianpaolo is taking the picture). The post-its on the wall are the user stories for <a href="http://www.microsoft.com/feeds/msdn/en-us/architecture/media/SaaS/NWH-DEMO-1-800-600.asx">Northwind Hosting</a> (I was happy to see <a href="http://code.google.com/appengine/">Google App Engine</a> six months later as a validation of our thinking).</p>
<p>I&#8217;ve witnessed the growth of Software as a Service since it was in the initial stages up to now that has started being adopted by the industry and lately has been extended to a broader term: <strong>Cloud Computing.</strong></p>
<p>The thesis is the sum of all the experience I gather along these years and it&#8217;s an attempt to summarize and compress the taxonomy of Software as a Service applications on a single model; that is more about &#8220;breadth&#8221; than &#8220;depth&#8221;. This model was based on <em>Feature Modeling, </em>a technique used in <em>Software Product Lines (SPL).</em> <em>Feature Modeling</em> is a method and notation to elicit and represent common and variable features of the system in a system family. It was first proposed by Kang et al in <a href="http://www.sei.cmu.edu/domain-engineering/FODA.html"><em>Feature Oriented Domain Analysis</em></a> by the Software Engineering Institute (SEI, 90). It&#8217;s been used lately in <a href="http://www.swen.uwaterloo.ca/~kczarnec/gsdoverview.pdf">Generative Software Development</a> (Czarnecki, 2005), which aims at modeling and implementing system families in such a way that a given system can be automatically generated from specification written in one or more textual or graphical domain specific languages (DSLs). Since SaaS and Cloud Computing are evolving fast I wanted to separate the problem space from the solution space allowing the individual development and growth of each of them. <em>Feature Modeling </em>helped because it was focused on the capabilities. I didn&#8217;t try to use <em>Feature Modeling </em>to automate the generation of this kind of systems, though. The priority was having a model that allow me to frame and explain Software as a Service systems.</p>
<p> </p>
<p align="center"><a href="http://blogs.southworks.net/mwoloski/files/2008/09/image2.png"><img src="http://blogs.southworks.net/mwoloski/files/2008/09/image-thumb1.png" border="0" alt="image" width="400" height="175" /></a></p>
<p align="center"><em>Separation between problem and solution space (Overview of Generative Software Development, Czarnecki)</em></p>
<p align="left">Part of defining the problem space consisted of doing a <em>domain analysis. </em>This is an activity of SPL aiming to characterize a domain by understanding their commonality and variability. If you follow this blog you might have read the <a href="http://blogs.southworks.net/mwoloski/2008/08/19/cloud-computing-taxonomy-map/">cloud computing taxonomy map post</a>. That was an exercise during the domain analysis that helped me understand the different scopes, offerings and features of Software as a Service.</p>
<p align="left"><a href="http://blogs.southworks.net/mwoloski/files/2008/09/image3.png"><img src="http://blogs.southworks.net/mwoloski/files/2008/09/image-thumb2.png" border="0" alt="image" width="720" height="307" /></a></p>
<p align="center"><em>Domain analysis of Software as a Service</em></p>
<p align="left">With this information, I&#8217;ve spent a couple of days pasting post-its on the wall, trying to group the features and capabilities in a way that makes sense. The end result was this &#8220;onion&#8221; diagram where each category holds the different features of Software as a Service.</p>
<p align="center"><a href="http://blogs.southworks.net/mwoloski/files/2008/09/image4.png"><img src="http://blogs.southworks.net/mwoloski/files/2008/09/image-thumb3.png" border="0" alt="image" width="460" height="278" /></a></p>
<p align="left">The model is later refined, from the taxonomy above to the capability layer (problem space) and finally to the implementation layer (solution space) as shown in the following figure.</p>
<p align="center"><a href="http://blogs.southworks.net/mwoloski/files/2008/09/image5.png"><img src="http://blogs.southworks.net/mwoloski/files/2008/09/image-thumb4.png" border="0" alt="image" width="350" height="329" /></a></p>
<p>The thesis then describes each of the capabilities in a high level fashion and then proposes patterns, architecture styles and technologies to implement those capabilities.</p>
<p>The following feature tree is an instance of the capability layer of the model for the <a href="http://www.codeplex.com/LitwareHr">LitwareHr</a> application (grayed capabilities are not part of LitwareHr system). This content is in Spanish, but it will be soon available in English.</p>
<p><a href="http://blogs.southworks.net/mwoloski/files/2008/09/image6.png"><img src="http://blogs.southworks.net/mwoloski/files/2008/09/image-thumb5.png" border="0" alt="image" width="720" height="559" /></a> </p>
<p>The thesis also includes other non technical aspects like</p>
<ul>
<li>Adoption and diffusion analysis of SaaS based on market research</li>
<li>Barriers for adoption</li>
<li>Historical context (starting from specialization in the 19th century, passing through outsourcing, mainframes and what not <img src='http://blogs.southworks.net/mwoloski/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Roles and ecosystem</li>
</ul>
<p>I want to thanks again to all the people that helped directly or indirectly: my family and fiancee, Alejandro Jack, Gustavo López, Eugenio Pace, Gianpaolo Carraro, Fred Chong, Arvindra Sehmi, Ariel Schapiro, Angel &#8220;Java&#8221; Lopez and to all Southworks.</p>
<p>Fell free to <a href="http://snipurl.com/3xbuj">download the Spanish version</a> and let me know if you find it useful to matias at southworks dot net.</p>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/405902689" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/09/28/thesis-software-as-a-service/feed/</wfw:commentRss>
<enclosure url="http://www.microsoft.com/feeds/msdn/en-us/architecture/media/SaaS/NWH-DEMO-1-800-600.asx" length="412" type="video/x-ms-asf" />
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F09%2F28%2Fthesis-software-as-a-service%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/09/28/thesis-software-as-a-service/</feedburner:origLink></item>
		<item>
		<title>Microsoft Identity Framework (Zermatt) #1</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/405079228/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/09/27/microsoft-identity-framework-zermatt-1/#comments</comments>
		<pubDate>Sat, 27 Sep 2008 23:16:16 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[Federation]]></category>

		<category><![CDATA[Identity Management]]></category>

		<category><![CDATA[Security Token Service]]></category>

		<category><![CDATA[Zermatt]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/?p=325</guid>
		<description><![CDATA[In these series I want to show the usage of Zermatt to solve some typical scenarios in identity management. I will assume that the reader is already familiar with concepts like security token service, claims, tokens, credentials, etc. If not, you can read this article from Vittorio Bertocci on July 2008 issue of the Architecture [...]]]></description>
			<content:encoded><![CDATA[<p>In these series I want to show the usage of Zermatt to solve some typical scenarios in identity management. I will assume that the reader is already familiar with concepts like security token service, claims, tokens, credentials, etc. If not, you can read <a href="http://msdn.microsoft.com/en-us/library/cc836390.aspx">this article</a> from Vittorio Bertocci on July 2008 issue of the <a href="http://msdn.microsoft.com/en-us/library/bb410935.aspx">Architecture Journal</a>.</p>
<p>This first post will be about the simplest scenario in identity management: the Active Client with a single STS. In other words, a client that calls a web service with a policy that says that you need to use a certain token to talk to him.</p>
<p><a href="http://blogs.southworks.net/mwoloski/files/2008/09/image.png"><img height="420" alt="image" src="http://blogs.southworks.net/mwoloski/files/2008/09/image-thumb.png" width="640" border="0" /></a></p>
<p>&#160;</p>
<p>The sequence of actions in this scenario is:</p>
<ol>
<li>Since the client needs to obtain a token before talk to the service, it will make a <strong>WS-Trust call</strong> to the <strong>STS</strong> sending some kind of credentials. It could be <strong>Windows credentials</strong>, a <strong>X509 certificate</strong>, <strong>username and password</strong> or maybe another token (we&#8217;ll leave that for a future post). </li>
<li>The STS will <strong>authenticate the caller</strong> and probably will <strong>output some claims</strong> about him. These claims might come from some repository like a database or AD. If the client is using Windows credentials, maybe the claims will be the groups the user belongs, the email and the full name. If the client is using username and password, the claims could be the roles stored in a database table. However, the claims could be anything you want that will be used later to perform access checks on the service. </li>
<li>The response is sent to the client containing an <strong>RSTR</strong> (Request Security Token Response) that will contain the requested <strong>security token with the claims</strong>. This token can be <strong>encrypted </strong>so only the service can decrypt it. For doing that, the STS will use the <strong>public key of the service</strong> certificate. The token will be also signed by the STS to avoid untrusted issuers. To sign the token, the <strong>STS will use a private key</strong>. </li>
<li>Finally, the client <strong>calls the service</strong> using the token obtained in 3. The service will only accept tokens of trusted issuers. Since there is a trust relationship between our STS and the service, the latter will have the <strong>public key of the STS </strong>that will allow him to check the signature of the token. </li>
</ol>
<p>Having the sequence of things defined, we&#8217;ll see how this can be achieved using Zermatt Beta 1. First, let me put some context on some of the decisions I will take.</p>
<p>One of the things I really like about Zermatt is the <strong>WSTrustClient</strong> class. This simple class allows anyone to issue a RST to an STS. If you ever tried to implement the approach depicted above with <strong>WCF</strong> you might have met with the <strong>wsFederationHttpBinding</strong>. This binding encapsulates the sequence above so the client <strong>doesn&#8217;t have to worry about the behind the scenes of obtaining</strong> <strong>tokens</strong>. While this is good in some cases, when I started playing with this identity architecture, I felt that there was some kind of <strong>&quot;black magic&quot; happening</strong>. As someone that uses Reflector as its primary tool to solve most of the challenges with emergent technologies, I wanted to know how all this worked and <strong>I wanted to have control over the tokens</strong>. Well, knowing the theory helps a lot. I also recommend you to use <strong>WSTrustClient&#160; </strong>and &quot;<strong>do it yourself</strong>&quot;.</p>
<h3>[1] Issue token</h3>
<p>We will use a simple username and password to call the STS. The following method uses the WSTrustClient class to call the STS in localhost:6001/IPSTS. Notice the usage of WCF WSHttpBinding with Windows credentials. The RequestType property of the RequestSecurityToken class is not the regular WS-Trust issue SOAP action URI(<a href="http://schemas.xmlsoap.org/ws/2004/04/security/trust/RST/Issue">http://schemas.xmlsoap.org/ws/2004/04/security/trust/RST/Issue</a>), but a custom one. This is because Zermatt supports different WS-Trust versions and will do the transformation to the correct URI on runtime depending on the WSTrust version (by default is Feb 2005 version)</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">static</span> SecurityToken GetToken(<span style="color: #0000ff">string</span> username, <span style="color: #0000ff">string</span> password)
{
    var binding = <span style="color: #0000ff">new</span> WSHttpBinding(SecurityMode.Message);
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
    binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

    var ipAddress = <span style="color: #0000ff">new</span> EndpointAddress(<span style="color: #006080">&quot;http://localhost:6001/IPSTS&quot;</span>);

    var client = <span style="color: #0000ff">new</span> WSTrustClient(binding, ipAddress);

    client.ClientCredentials.Windows.ClientCredential.UserName = username;
    client.ClientCredentials.Windows.ClientCredential.Password = password;

    var rst = <span style="color: #0000ff">new</span> RequestSecurityToken();
    rst.RequestType = <span style="color: #006080">&quot;http://schemas.microsoft.com/idfx/requesttype/issue&quot;</span>;
    var token = client.Issue(rst);
    <span style="color: #0000ff">return</span> token;
}</pre>
</div>
<h3>[2] Authenticate &amp; fill tokens with claims</h3>
<p>The STS in Zermatt have two methods to override. The first is GetScope which provides information related to the &quot;scope&quot; where this STS will be used (things like certificates to use to encrypt, to sign, etc) The second is GetOutputSubjects that will provide information about the subject (like claims). Here we are creating one claim of type http://schemas.xmlsoap.org/claim/Group for each group the user belongs.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> ClaimsIdentityCollection GetOutputSubjects(Scope scope, IClaimsPrincipal principal, RequestSecurityToken request)
{
    var claimsIdentities = <span style="color: #0000ff">new</span> ClaimsIdentityCollection();
    var wI = (WindowsIdentity)principal.Identity;
    var identity = <span style="color: #0000ff">new</span> ClaimsIdentity(principal.Identity);

    <span style="color: #0000ff">foreach</span> (IdentityReference iD <span style="color: #0000ff">in</span> wI.Groups)
    {
        var groupName = <span style="color: #0000ff">new</span> SecurityIdentifier(iD.Value).Translate(<span style="color: #0000ff">typeof</span>(NTAccount)).ToString();
        identity.Claims.Add(<span style="color: #0000ff">new</span> Claim(Constants.GroupClaimType, groupName));
    }
    claimsIdentities.Add(identity);

    <span style="color: #0000ff">return</span> claimsIdentities;
}</pre>
</div>
<h3>[3] Encrypting and signing the RSTR</h3>
<p>In the <strong>GetScope</strong> method we are indicating how we are going to encrypt and sign the token</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> Scope GetScope(IClaimsPrincipal principal, RequestSecurityToken request)
{
    Scope scope = <span style="color: #0000ff">new</span> Scope(request, SecurityTokenServiceConfiguration.SigningCredentials);

    scope.EncryptingCredentials = <span style="color: #0000ff">new</span> X509EncryptingCredentials(
                                      CertificateUtil.GetCertificateByThumbprint(StoreName.TrustedPeople,
                                                                      StoreLocation.LocalMachine,
                                                                      Constants.EncryptingCertificateThumbprint));
    <span style="color: #0000ff">return</span> scope;
}</pre>
</div>
<h3>[4] Call the service using the token</h3>
<p>At this point the client have a token in his hands. Now we need to use it on the outgoing message (on the WS-Security header). Here, we use the <strong>WSTrustClientCredentials</strong> class and set the <strong>SecurityToken</strong> we obtained before.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> CallService(SecurityToken token)
{
    var client = <span style="color: #0000ff">new</span> ShippingManagerClient();

    var credentials = <span style="color: #0000ff">new</span> WSTrustClientCredentials();
    credentials.IssuedSecurityToken = token;
    client.Endpoint.Behaviors.Remove&lt;ClientCredentials&gt;();
    client.Endpoint.Behaviors.Add(credentials);
    credentials.ConfigureChannel(client.InnerChannel);

    client.NewShipment();
    client.Close();
}</pre>
</div>
<p>The client will use a custom binding (not the wsFederationHttpBinding). Notice the issuer address is <a href="http://notused">http://notused</a>. We can do this because we are using <strong>WSTrustClientCredentials</strong> that creates a custom <strong>WCF</strong>&#160;<strong>IssuedSecurityTokenProvider</strong>. This provider will shortcircuit the interaction with the issuer and will simply return the token we set in the <strong>IssuedSecurityToken</strong> on <strong>WSTrustClientCredentials</strong>.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">&lt;</span><span style="color: #800000">bindings</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">customBinding</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">binding</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">=&quot;CustomBinding_IShippingManager&quot;</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span><span style="color: #800000">security</span> <span style="color: #ff0000">defaultAlgorithmSuite</span><span style="color: #0000ff">=&quot;Default&quot;</span> <span style="color: #ff0000">authenticationMode</span><span style="color: #0000ff">=&quot;IssuedTokenForCertificate&quot;</span>
                <span style="color: #ff0000">requireDerivedKeys</span><span style="color: #0000ff">=&quot;true&quot;</span> <span style="color: #ff0000">securityHeaderLayout</span><span style="color: #0000ff">=&quot;Strict&quot;</span> <span style="color: #ff0000">includeTimestamp</span><span style="color: #0000ff">=&quot;true&quot;</span>
                <span style="color: #ff0000">keyEntropyMode</span><span style="color: #0000ff">=&quot;CombinedEntropy&quot;</span> <span style="color: #ff0000">messageProtectionOrder</span><span style="color: #0000ff">=&quot;SignBeforeEncryptAndEncryptSignature&quot;</span>
                <span style="color: #ff0000">messageSecurityVersion</span><span style="color: #0000ff">=&quot;WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10&quot;</span>
                <span style="color: #ff0000">requireSignatureConfirmation</span><span style="color: #0000ff">=&quot;true&quot;</span><span style="color: #0000ff">&gt;</span>
                <span style="color: #0000ff">&lt;</span><span style="color: #800000">issuedTokenParameters</span> <span style="color: #ff0000">keyType</span><span style="color: #0000ff">=&quot;SymmetricKey&quot;</span> <span style="color: #ff0000">tokenType</span><span style="color: #0000ff">=&quot;http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1&quot;</span><span style="color: #0000ff">&gt;</span>
                    <span style="color: #0000ff">&lt;</span><span style="color: #800000">issuer</span> <span style="color: #ff0000">address</span><span style="color: #0000ff">=&quot;http://notused&quot;</span> <span style="color: #ff0000">binding</span><span style="color: #0000ff">=&quot;wsHttpBinding&quot;</span> <span style="color: #0000ff">/&gt;</span>
                    <span style="color: #0000ff">&lt;</span><span style="color: #800000">issuerMetadata</span> <span style="color: #ff0000">address</span><span style="color: #0000ff">=&quot;http://notused/mex&quot;</span> <span style="color: #0000ff">/&gt;</span>
                <span style="color: #0000ff">&lt;/</span><span style="color: #800000">issuedTokenParameters</span><span style="color: #0000ff">&gt;</span>
                <span style="color: #0000ff">&lt;</span><span style="color: #800000">localClientSettings</span> <span style="color: #ff0000">cacheCookies</span><span style="color: #0000ff">=&quot;true&quot;</span> <span style="color: #ff0000">detectReplays</span><span style="color: #0000ff">=&quot;true&quot;</span>
                    <span style="color: #ff0000">replayCacheSize</span><span style="color: #0000ff">=&quot;900000&quot;</span> <span style="color: #ff0000">maxClockSkew</span><span style="color: #0000ff">=&quot;00:05:00&quot;</span> <span style="color: #ff0000">maxCookieCachingTime</span><span style="color: #0000ff">=&quot;Infinite&quot;</span>
                    <span style="color: #ff0000">replayWindow</span><span style="color: #0000ff">=&quot;00:05:00&quot;</span> <span style="color: #ff0000">sessionKeyRenewalInterval</span><span style="color: #0000ff">=&quot;10:00:00&quot;</span>
                    <span style="color: #ff0000">sessionKeyRolloverInterval</span><span style="color: #0000ff">=&quot;00:05:00&quot;</span> <span style="color: #ff0000">reconnectTransportOnFailure</span><span style="color: #0000ff">=&quot;true&quot;</span>
                    <span style="color: #ff0000">timestampValidityDuration</span><span style="color: #0000ff">=&quot;00:05:00&quot;</span> <span style="color: #ff0000">cookieRenewalThresholdPercentage</span><span style="color: #0000ff">=&quot;60&quot;</span> <span style="color: #0000ff">/&gt;</span>
                <span style="color: #0000ff">&lt;</span><span style="color: #800000">localServiceSettings</span> <span style="color: #ff0000">detectReplays</span><span style="color: #0000ff">=&quot;true&quot;</span> <span style="color: #ff0000">issuedCookieLifetime</span><span style="color: #0000ff">=&quot;10:00:00&quot;</span>
                    <span style="color: #ff0000">maxStatefulNegotiations</span><span style="color: #0000ff">=&quot;128&quot;</span> <span style="color: #ff0000">replayCacheSize</span><span style="color: #0000ff">=&quot;900000&quot;</span> <span style="color: #ff0000">maxClockSkew</span><span style="color: #0000ff">=&quot;00:05:00&quot;</span>
                    <span style="color: #ff0000">negotiationTimeout</span><span style="color: #0000ff">=&quot;00:01:00&quot;</span> <span style="color: #ff0000">replayWindow</span><span style="color: #0000ff">=&quot;00:05:00&quot;</span> <span style="color: #ff0000">inactivityTimeout</span><span style="color: #0000ff">=&quot;00:02:00&quot;</span>
                    <span style="color: #ff0000">sessionKeyRenewalInterval</span><span style="color: #0000ff">=&quot;15:00:00&quot;</span> <span style="color: #ff0000">sessionKeyRolloverInterval</span><span style="color: #0000ff">=&quot;00:05:00&quot;</span>
                    <span style="color: #ff0000">reconnectTransportOnFailure</span><span style="color: #0000ff">=&quot;true&quot;</span> <span style="color: #ff0000">maxPendingSessions</span><span style="color: #0000ff">=&quot;128&quot;</span>
                    <span style="color: #ff0000">maxCachedCookies</span><span style="color: #0000ff">=&quot;1000&quot;</span> <span style="color: #ff0000">timestampValidityDuration</span><span style="color: #0000ff">=&quot;00:05:00&quot;</span> <span style="color: #0000ff">/&gt;</span>
                <span style="color: #0000ff">&lt;</span><span style="color: #800000">secureConversationBootstrap</span> <span style="color: #0000ff">/&gt;</span>
            <span style="color: #0000ff">&lt;/</span><span style="color: #800000">security</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span><span style="color: #800000">textMessageEncoding</span> <span style="color: #ff0000">maxReadPoolSize</span><span style="color: #0000ff">=&quot;64&quot;</span> <span style="color: #ff0000">maxWritePoolSize</span><span style="color: #0000ff">=&quot;16&quot;</span>
                <span style="color: #ff0000">messageVersion</span><span style="color: #0000ff">=&quot;Default&quot;</span> <span style="color: #ff0000">writeEncoding</span><span style="color: #0000ff">=&quot;utf-8&quot;</span><span style="color: #0000ff">&gt;</span>
                <span style="color: #0000ff">&lt;</span><span style="color: #800000">readerQuotas</span> <span style="color: #ff0000">maxDepth</span><span style="color: #0000ff">=&quot;32&quot;</span> <span style="color: #ff0000">maxStringContentLength</span><span style="color: #0000ff">=&quot;8192&quot;</span> <span style="color: #ff0000">maxArrayLength</span><span style="color: #0000ff">=&quot;65536&quot;</span>
                    <span style="color: #ff0000">maxBytesPerRead</span><span style="color: #0000ff">=&quot;4096&quot;</span> <span style="color: #ff0000">maxNameTableCharCount</span><span style="color: #0000ff">=&quot;16384&quot;</span> <span style="color: #0000ff">/&gt;</span>
            <span style="color: #0000ff">&lt;/</span><span style="color: #800000">textMessageEncoding</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span><span style="color: #800000">httpTransport</span> <span style="color: #ff0000">manualAddressing</span><span style="color: #0000ff">=&quot;false&quot;</span> <span style="color: #ff0000">maxBufferPoolSize</span><span style="color: #0000ff">=&quot;524288&quot;</span>
                <span style="color: #ff0000">maxReceivedMessageSize</span><span style="color: #0000ff">=&quot;65536&quot;</span> <span style="color: #ff0000">allowCookies</span><span style="color: #0000ff">=&quot;false&quot;</span> <span style="color: #ff0000">authenticationScheme</span><span style="color: #0000ff">=&quot;Anonymous&quot;</span>
                <span style="color: #ff0000">bypassProxyOnLocal</span><span style="color: #0000ff">=&quot;false&quot;</span> <span style="color: #ff0000">hostNameComparisonMode</span><span style="color: #0000ff">=&quot;StrongWildcard&quot;</span>
                <span style="color: #ff0000">keepAliveEnabled</span><span style="color: #0000ff">=&quot;true&quot;</span> <span style="color: #ff0000">maxBufferSize</span><span style="color: #0000ff">=&quot;65536&quot;</span> <span style="color: #ff0000">proxyAuthenticationScheme</span><span style="color: #0000ff">=&quot;Anonymous&quot;</span>
                <span style="color: #ff0000">realm</span><span style="color: #0000ff">=&quot;&quot;</span> <span style="color: #ff0000">transferMode</span><span style="color: #0000ff">=&quot;Buffered&quot;</span> <span style="color: #ff0000">unsafeConnectionNtlmAuthentication</span><span style="color: #0000ff">=&quot;false&quot;</span>
                <span style="color: #ff0000">useDefaultWebProxy</span><span style="color: #0000ff">=&quot;true&quot;</span> <span style="color: #0000ff">/&gt;</span>
        <span style="color: #0000ff">&lt;/</span><span style="color: #800000">binding</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">customBinding</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">bindings</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>On the service side we want to check that the token was issued by someone we trust. To do that, Zermatt provides something called <strong>SamlSecurityTokenRequirements </strong>(this code is somewhere in the host).&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace">var handler = collection[<span style="color: #0000ff">typeof</span>(SamlSecurityToken)] <span style="color: #0000ff">as</span> Saml11TokenHandler;
handler.SamlSecurityTokenRequirement.IssuerTokenAuthenticators.Clear();
handler.SamlSecurityTokenRequirement.IssuerTokenAuthenticators.Add(
   <span style="color: #0000ff">new</span> X509SecurityTokenAuthenticator(
      <span style="color: #0000ff">new</span> TokenIssuerCertificateValidator(Constants.IssuerCertificateThumbprint)));   </pre>
</div>
<p>The <strong>TokenIssuerCertificateValidator</strong> derives from <strong>X509CertificateValidator</strong> which has a virtual method <strong>ValidateToken</strong>. The input parameter of this method is the certificate used to sign the token. The following code will check the thumbprint of the incoming token is the one we expect.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> Validate( X509Certificate2 incoming )
{
    <span style="color: #0000ff">if</span> ( incoming.Thumbprint != issuerCertificate.Thumbprint )
    {
        <span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> SecurityTokenException( <span style="color: #006080">&quot;Issuer certificate validation failed&quot;</span> );
    }
}</pre>
</div>
<p>Since the service has the private key that allows decrypting the token, we can read the claims. Zermatt will populate the <strong>ClaimsPrincipal</strong> object that will be accessible from any place in the service pipeline. The <strong>WCF</strong> <strong>ServiceAuthorizationManager</strong> might be the place where you want to do check access using the <strong>ClaimsPrincipal</strong>.</p>
<div>
<pre style="padding-right: 0px;padding-left: 0px;font-size: 8pt;padding-bottom: 0px;margin: 0em;width: 100%;color: black;padding-top: 0px;font-family: consolas, &#39;Courier New&#39;, courier, monospace">var identity = ClaimsPrincipal.Current.Identity <span style="color: #0000ff">as</span> IClaimsIdentity;
identity.Claims&#8230;</pre>
</div>
<div>&#160;</div>
<div>This is the end of the first post on Identity and Zermatt. Next one will be the passive client.</div>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/405079228" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/09/27/microsoft-identity-framework-zermatt-1/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F09%2F27%2Fmicrosoft-identity-framework-zermatt-1%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/09/27/microsoft-identity-framework-zermatt-1/</feedburner:origLink></item>
		<item>
		<title>Creating Security Token Services with Microsoft Identity Framework (Zermatt)</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/371143865/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/08/21/creating-security-token-services-with-microsoft-identity-framework-zermatt/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 23:56:29 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[Federation]]></category>

		<category><![CDATA[Identity Management]]></category>

		<category><![CDATA[Security Token Service]]></category>

		<category><![CDATA[Zermatt]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/2008/08/21/creating-security-token-services-with-microsoft-identity-framework-zermatt/</guid>
		<description><![CDATA[ Couple of weeks ago I posted about Zermatt and how Security Token Services and Claim Based authorization can help&#160; in the Identity Management area. 

Sebastian who has been working with Zermatt for a couple of weeks already, is posting a useful “straight to the point” how to implement active and passive STS’s using Zermatt. [...]]]></description>
			<content:encoded><![CDATA[<p><img height="111" alt="image" src="http://blogs.southworks.net/mwoloski/files/2008/08/image.png" width="172" align="right" /> Couple of weeks ago I <a href="http://blogs.southworks.net/mwoloski/2008/07/12/identity-prime-time-with-microsoft-identity-framework-zermatt/">posted</a> about <a href="https://connect.microsoft.com/site/sitehome.aspx?SiteID=642">Zermatt</a> and how Security Token Services and Claim Based authorization can help&#160; in the Identity Management area. </p>
</p>
<p><a href="http://blogs.southworks.net/siacomuzzi/">Sebastian</a> who has been working with Zermatt for a couple of weeks already, is <a href="http://blogs.southworks.net/siacomuzzi/2008/08/20/how-to-make-an-activepassive-sts-using-zermatt/">posting</a> a useful “straight to the point” how to implement active and passive STS’s using Zermatt. The abstractions in Zermatt are making this a joy. I like the separation of the STS from the underlying host (i.e. ASP.NET, WCF, “put-the-name-of-the-next-foundation”) because allows you to reuse the same STS for both the service layer and the presentation layer and have a consistent access control mechanism on both layers using claims.</p>
<p>Also, while we are on the subject, I recommend you to read the <a href="http://download.microsoft.com/download/a/7/6/a76e5770-19b1-415b-8b6c-6ff5c7b71574/J16_EN.zip">latest Architecture Journal on Identity</a>. I just read Vittorio’s article and it has all the things you need to know about the underlying concepts.</p>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/371143865" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/08/21/creating-security-token-services-with-microsoft-identity-framework-zermatt/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F08%2F21%2Fcreating-security-token-services-with-microsoft-identity-framework-zermatt%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/08/21/creating-security-token-services-with-microsoft-identity-framework-zermatt/</feedburner:origLink></item>
		<item>
		<title>Cloud Computing Taxonomy Map</title>
		<link>http://feeds.southworks.net/~r/mwoloski/~3/369369738/</link>
		<comments>http://blogs.southworks.net/mwoloski/2008/08/19/cloud-computing-taxonomy-map/#comments</comments>
		<pubDate>Wed, 20 Aug 2008 01:13:29 +0000</pubDate>
		<dc:creator>Matias Woloski</dc:creator>
		
		<category><![CDATA[Cloud Computing]]></category>

		<category><![CDATA[SaaS]]></category>

		<category><![CDATA[Taxonomy]]></category>

		<guid isPermaLink="false">http://blogs.southworks.net/mwoloski/2008/08/19/cloud-computing-taxonomy-map/</guid>
		<description><![CDATA[Lately the term SaaS became a broader term and now it is called Cloud Computing (see David Chappell’s paper and Wikipedia). It includes the whole paradigm of utility computing + saas + platform as a service + * as a service.
I’ve got good feedback on the taxonomy map from the blogsphere (including Jeff Kaplan, from [...]]]></description>
			<content:encoded><![CDATA[<p>Lately the term SaaS became a broader term and now it is called Cloud Computing (see <a href="http://www.davidchappell.com/CloudPlatforms--Chappell.pdf">David Chappell’s paper</a> and <a href="http://en.wikipedia.org/wiki/Cloud_computing">Wikipedia</a>). It includes the whole paradigm of utility computing + saas + platform as a service + * as a service.</p>
<p>I’ve got good feedback on the <a href="http://blogs.southworks.net/mwoloski/2008/07/10/saas-taxonomy-map/">taxonomy map</a> from <a href="http://et.cairene.net/2008/07/28/the-cloud-services-stack-infrastructure/">the</a> <a href="http://westcoastgrid.blogspot.com/2008/07/robert-continues-to-nail-cloud-taxonomy.html">blogsphere</a> (including <a href="https://www.blogger.com/comment.g?blogID=20200634&amp;postID=3027163501138143168">Jeff Kaplan</a>, from THINK IT Services). I updated the map some time ago but didn’t have time to publish. So here it is rather sooner than later. (I need <a href="http://blogs.southworks.net/pcostantini">Pablo</a>’s help to do the animated GIF, so this time is static)</p>
<p>&#160;</p>
<p><a href="http://blogs.southworks.net/mwoloski/files/2008/08/posterfeatures.png"><img height="480" alt="Cloud Taxonomy Map Features" src="http://blogs.southworks.net/mwoloski/files/2008/08/posterfeatures-thumb.png" width="640" /></a> </p>
</p>
</p>
</p>
</p>
</p>
</p>
</p>
</p>
</p>
</p>
<p>&#160;</p>
<p><a href="http://blogs.southworks.net/mwoloski/files/2008/08/posterservices.png"><img height="480" alt="Cloud Taxonomy Map Services" src="http://blogs.southworks.net/mwoloski/files/2008/08/posterservices-thumb.png" width="640" /></a></p>
<img src="http://feeds.southworks.net/~r/mwoloski/~4/369369738" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.southworks.net/mwoloski/2008/08/19/cloud-computing-taxonomy-map/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=mwoloski&amp;itemurl=http%3A%2F%2Fblogs.southworks.net%2Fmwoloski%2F2008%2F08%2F19%2Fcloud-computing-taxonomy-map%2F</feedburner:awareness><feedburner:origLink>http://blogs.southworks.net/mwoloski/2008/08/19/cloud-computing-taxonomy-map/</feedburner:origLink></item>
	<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetFeedData?uri=mwoloski</feedburner:awareness></channel>
</rss>
