Rule Based Access Control using an Expression Evaluator

September 17, 2008

I’ve written previously about “claims based authorization,” and how I believe it will eventually become a ubiquitous approach to identity management as the world of online digital identity reinvents itself in order to avoid implosion. If you aren’t familiar with the concept of claims based identity, I recommend checking out the post linked above or following some of the links from this post.  If you just want to examine the sample code for this post, it is here.

In this post I’m interested in how a set of claims presented by a user when making a service call can be evaluated against specific authorization rules to determine whether or not the user has access to the requested resource.

The details of how a user is associated with such claims, how they are secured, and how claims are embedded inside calls to your service are beyond the scope of this post, but the links listed above should provide a place to put the tip of that chisel. For the purposes of this post I will assume that claims are presented via a list of IClaim objects, and an IClaim is nothing but a Name/Value pair – IList<IClaim>. This is very similar to how Micrisofts new Zermatt Identity Framework represents claims, and this was intentional as I believe that Zermatt is probably the future of Identity Management on the .NET platform.

So then, given IList<IClaim> claims, how can we make rational authorization decisions, such as “I only want users who are in the Premium Members role and whose age is older than 21 to access this (probably seedy) service method.” One obvious, simple approach would be to evaluate the claims programmatically. Some simple extension methods can make this much easier:

public static class ClaimsExtensions
{
   public static T GetClaimValue<t>(this IList<iclaim> claims, string claimType)
   {
       foreach (IClaim claim in claims)
       {
           if (String.Compare(claim.ClaimType, claimType, true) == 0)
           {
               return TypeNormalizer.EnsureType<t>(claim.Value, default(T));
           }
       }
       return default(T);
   }

   public static bool ClaimEqualsAny(this IList<iclaim> claims, string claimType, string claimValue)
   {
       foreach (IClaim claim in claims)
       {
           if (String.Compare(claim.ClaimType, claimType, true) == 0)
           {
               if (claim.Value.Equals(claimValue, StringComparison.InvariantCultureIgnoreCase))
                   return true;
           }
       }
       return false;
   }

   public static bool EvaluateClaim<t>(this IList<iclaim> claims, string claimType, Func<t , bool> eval)
   {
       var claimValue = claims.GetClaimValue</t><t>(claimType);
       return eval(claimValue);
   }
}

Then, from within a method that needs protecting, you can easily do something like this:

public void MyServiceMethod()
{
    if (CurrentUser.Claims.EvaluateClaim<int>(CustomClaimTypes.AgeInYears,age => age < 21) ||
        CurrentUser.Claims.ClaimEqualsAny(CustomClaimTypes.Role,"Premium User") == false)
    {
	//Whatever you do when someone isn't authorized. Throw a not authorized exception? Return a fault code?
    }

    //Implement your service method here, your user is old enough and has paid their money
}

If you were clever, you could probably figure out a way to use LINQ expressions to make the syntax even cleaner. This is all good and well, but it has at least one major problem – authorization rules are probably likely to change far more frequently than your application code. Even worse, you may wish your power users to be able to manage their own authorization rules for certain kinds of access or for named permissions. Using the technique described above, any change to any authorization rule will require you compile and deploy your application.

One common solution to conundrums such as these is to use a DSL (Domain Specific Language). And while you certainly could write a custom DSL to implement your authorization rules, authorization rules have an interesting characteristic: they always resolve to a discrete value, a true or a false. They are simply boolean expressions.

There are a number of Expression Evaluators available from the open source community that will fit the bill perfectly. An Expression Evaluator will allow you to specify your authorization rules as simple strings, which means they can be stored in a configuration file or a database or some other persistent store and modified and run-time as needed. They are also serializable by definition and can easily be requested by and cached at the user interface to allow the user interface to use the same authorization logic  to render itself appropriately with respect to the permissions of the currently logged in user that the server will use to authorize access to its API without (necessarily) having any code in common other than a reference to the same expression evaluator library.

In this example I will be using Simple Expression Evaluator available on Codeplex. I chose this library purely out of nepotism, because I wrote it, but you should be able to use any expression evaluator that catches your fancy. A number of options for .NET are listed here.

Using an Simple Expression Evaluator we could rewrite the above authorization rule like this:

AgeInYears >= 21 and MatchesAny(Role = "Premium User")

In the sample project I added a custom function, IsInRole, allowing this syntax:

AgeInYears >= 21 and IsInRole("Premium User")

To make this happen, Simple Expression Evaluator will need a little help in interpreting claim names. The main reason behind this is that claims are usually represented by a URI, such as http://thefreakparade.com/claims/role, but accessed through code using string constants, such as

public static class CustomClaimTypes
{
     public const string Role = "http://thefreakparade.com/claims/role";
     //...more...
}

and therefore accessed in code like this:

var claim = new Claim(CustomClaimTypes.AgeInYears,43);

The expression evaluator will interperet something like AgeInYears to be a variable, and the name AgeInYears won’t naturally correspond to anything, because it’s really just a property name, the real claim is represented by a URI that would be far too ugly to stick in an expression. The solution is to give the expression evaluator a little help when evaluating variables, like so:

public bool Authorize(IList<iclaim> claims,string authExpression)
{
    var context = new ExpressionContext(claims);

    context.ResolveUnknownVariable +=
        (sender, args) =>
            {
               args.VariableValue =
                 claims.GetClaimValue(_claimAliases[args.VariableName]);

            };

    context.ResolveMissingFunction +=
        (sender, args) =>
            {
                if (args.FunctionName.Equals("IsInRole",StringComparison.OrdinalIgnoreCase))
                {
                    args.Function = (funcArgs) => IsInRole(claims,funcArgs);
                }
            };

    return ExpressionEvaluator.EvaluateExpression(authExpression,context);    

}

This method was modified a little from the actual sample to the purpose of clarity, but the general idea is the same. Also demonstrated is the technique required to add an IsInRole method to the expression language. The actual implementation of the IsInRole functionality is implemented off screen, see the sample for the actual code. This method also relies on a hashtable called _claimAliases being pre-populated with a mapping between the URI of a claim type and the friendly name the expression language will use. In the sample app, I simply used reflection to load the alias table with a mapping between the field name of each const and the actual URI.

Now, if you simple use the expression evaluator an call Authorize from within your service methods, like this:

public void MyServiceMethod()
{
    if (AuthorizationHelper.Authorize(
           CurrentUser.Claims,"AgeInYears >= 21 and IsInRole('Premium User')" == false)
    {
	//Whatever you do when someone isn't authorized. Throw a not authorized exception? Return a fault code?
    }

    //Implement your service method here, your user is old enough and has paid their money
}

Then all we added with the dynamic expression was complexity – your rules are still defined inline in your code. What you really want is a syntax like this:

public void MyServiceMethod()
{
    if (AuthorizationManager.Authorize(CurrentUser.Claims,Permissions.CanAccessServiceMethod) == false)
    {
        //no access
    }
    //service code
}

Where Permissions.CanAccessServiceMethod will key into a persistent authorization rule store such as a config file or database, so that the rule expressions themselves can be dynamically loaded at runtime and therefore modified outside of the code. The sample application takes advantage of a very simplified implementation of the Repository pattern and introduces an IAuthorizationRuleRepository to solve that issue. If you were really, really smart you could get to a syntax like this without much extra effort. Note this sample application does not quite go this far, but it shouldn’t be a stretch for you get there yourself if you care to:

[RequiresPermission(Permissions.CanAccessServiceMethod)]
public void MyServiceMethod()
{
    //service code
}

The only caveat with an attribute based approach is that access to your protected method is all or nothing. You can’t return a set of records filtered one way when one permission level is present, and another for a lower level of permission. But nothing would prevent you from mixing an attribute based approach with an inline-code based approach as appropriate.

Finally, here is a sample of the actual authorization syntax as implemented by the Identity at Rest sample application:

public List<monkey> ListAllMonkeys()
{
    //Only administrators can list all monkeys.
    //Everyone else can just list shaved monkeys.
    if (AuthorizeFor(
            Permissions.MonkeyShavingService.CanViewUnshavedMonkeys) == false)
    {
        return ListMonkeysByStatus(MonkeyStatus.ShavedClean.ToString());
    }

    return _monkeys;
}

And that’s about it. If you’ve made it this far, your very well aware that this post is describing a general approach to claims based authorization using an expression oriented DSL – the code samples listed here aren’t detailed enough to get you from point A to point B in an actual implementation. However, the included sample application, which is an evolution of the Identity At Rest sample application provided for this post, does provide an end to end application that fully implements the concepts discussed here. The sample comes with a “smart client” Winforms application that uses WCF to communicate with a remote  REST based API. All API calls are secured using the above described techniques.

I would be the last one to suggest that this approach is a “best practice” in managing claims based authorization, but it made sense to us and seems to work pretty well so far.  As always, I’d love to hear about any other approaches that you may be using.

Flowing Identity from a Client to a Service when using RESTful WCF Part 2 – A Solution

September 1, 2008

This post will describe a technique to transparently insert a custom HTTP header into all requests generated by a WCF REST proxy, as well as a technique to extract that HTTP header from the request at the service for the purpose of flowing the digital identity of an authenticated user from a REST client to a REST service. In this case, digital identity is represented by an authorization token, which is just a string. You can read a detailed description of the problem in Part 1 of this post. A complete sample project containing the full source code of the solution is on CodePlex.

The basic idea is to insert a custom action into the WCF message pipeline that will extract a security token representing the identity of the currently logged in user and add the value of that token (just a string) to the outgoing API call (an HTTP request) by way of a custom HTTP header. Once the request is received by the service, a custom action inserted into the receive pipeline checks for the custom header and, upon finding it, de-serializes the identity token and uses the claims contained within it to set an appropriate security context (in this case by setting Thread.CurrentPrincipal).

Setting a Custom HTTP Header – The Easy Way

On the client side, I am making the assumption that a user has been authenticated somehow, is associated with a set of claims, and that a representation of the user along with her claims can be found at Thread.CurrentPrincipal. In anticipation of using Microsoft’s new Zermatt Identity framework, which introduces IClaimsPrincipal and IClaimsIdentity, we implemented our own versions of these interfaces. They will eventually be replaced by the Zermatt types once we start integrating Zermatt into our application. IClaimsPrincipal maintains a reference to IClaimsIdentity, which has a property of type IList<IClaim> that represents all the authorization relevant attributes of a user. Please see this post for a discussion of claims based identity management. The interface IClaim is pretty much just a name value pair.

Adding a custom header to a request is trivial if you add the header in the same scope as the service call made on the proxy. You can just wrap the entire call in an OperationContextScope using statement, and use the Headers property of WebOperationContext.Current:

using (var factory = new WebChannelFactory<imyservice>())
{
  IMyService proxy = factory.CreateChannel();
  using (new OperationContextScope((IClientChannel) proxy))
  {
    WebOperationContext.Current.OutgoingRequest.Headers.Add('x-mycompany-auth',
                                                            'tokenString');
    proxy.DoItToIt();
  }
}

That technique works, and would probably be just fine if you only needed to add the authorization token to a few select calls. However, in our scenario, we want to add the token to *every* call, so wrapping each API call with all that scoping garbage isn’t going to cut it. It’s ugly and about as un-DRY as it gets.

Extending WCF – The Transparent Way

The solution, of course, is to take advantage of the WCF extensibility points available to both the client and the server. We want to choose spots in the messaging pipelines as close to the actual delivery/receipt of the message as possible.That would be the the Message Inspection phase on the client and the Operation Context Initialization phase on the server.

WCF can be made to jump through our hoops by following these steps:

On the client side we need to

1. Define the MessageInspector

2. Create a behavior to register the MessageInspector

3. Install the behavior on the channel factory.

On the service side we need to

4. Define a OperationContextInitializer

5. Create a behavior to register the extension

6. Apply the behavior to the service.

The end result is that Thread.CurrentPrincipal on the service side will always reference an IClaimsPrincipal with the same claims associated with the Thread.CurrentPrincipal on the service consumer, and we can test those claims to authorize access, as demonstrated in

7. Use.

1. The MessageInspector

 public class ClientAuthMessageInspector : IClientMessageInspector
 {
        #region IClientMessageInspector Members

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            //Get the HttpRequestMessage property from the Message
            var httpRequest =
                request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;

            //Make sure we have a valid property, or create one
            if (httpRequest == null)
            {
                httpRequest = new HttpRequestMessageProperty();
                request.Properties.Add(HttpRequestMessageProperty.Name, httpRequest);
            }

            //Add your token to the header. Simple as that.
            //In real life, we injected an ITokenProvider using an IoC,
            //instead of using static methods directly, but that was
            //overkill for a sample.
            httpRequest.Headers.Add(AuthenticationHelper.AUTH_TOKEN_HEADER_NAME,
                                    AuthenticationHelper.GetAuthTokenForCurrentUser());

            return null;
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            //nop
        }

        #endregion
 }

2. The Behavior

public class ClientAuthBehavior : IEndpointBehavior
{
        private readonly ClientAuthMessageInspector _messageInspector;

        public ClientAuthBehavior(ClientAuthMessageInspector messageInspector)
        {
            _messageInspector = messageInspector;
        }

        #region IEndpointBehavior Members

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            //Install the message inspector
            clientRuntime.MessageInspectors.Add(_messageInspector);
        }

        //no-op method implementations elided for clarity.
	//See the sample project for the complete
	//code listing.

        #endregion
}

3. Apply

 private void InitializeChannelFactory()
 {
    _channelFactory = new WebChannelFactory<imonkeyshavingservice>("shavingService");
    _channelFactory.Endpoint.Behaviors.Add(new ClientAuthBehavior());
 }

4. On the Service Side…OperationContextInitializer

 public class ClaimsAuthContextInitializer : ICallContextInitializer
 {
     #region ICallContextInitializer Members
      public Object BeforeInvoke(InstanceContext instanceContext,
                                IClientChannel channel,
                                Message message)
     {
         DetectCurrentUser();
         return null;
     }

     public void AfterInvoke(Object correlationState)
     {
     }
     #endregion

     private static void DetectCurrentUser()
     {
         if (WebOperationContext.Current == null)
             throw new InvalidOperationException("Only HTTP web requests are supported for this version of the API");

          string authToken = WebOperationContext.Current
             .IncomingRequest
             .Headers[AuthenticationHelper.AUTH_TOKEN_HEADER_NAME];

         if (AuthenticationHelper.SetCurrentUserFromAuthToken(authToken) == false)
         {
             WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
                throw new UnauthorizedAccessException(
                 "No authentication token was found in the headers of the current request.");
         }
    }
 }

5. The Behavior

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class ClaimsAuthServiceBehavior : Attribute, IServiceBehavior
    {
        #region IServiceBehavior Members

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
                                         Collection<serviceendpoint> endpoints,
                                         BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
            {
                var cd = cdb as ChannelDispatcher;

                if (cd != null)
                {
                    foreach (EndpointDispatcher ed in cd.Endpoints)
                    {

                        foreach (var dispatchOperation in
                            ed.DispatchRuntime.Operations)
                        {
                            dispatchOperation.CallContextInitializers
                                .Add(new ClaimsAuthContextInitializer());
                        }

                    }
                }
            }
        }

        #endregion

6. Apply

 static void Main(string[] args)
 {
      _host = new WebServiceHost(typeof(MonkeyShavingService),
                                 new Uri("http://localhost:8000"));

      _host.Description.Behaviors.Add(new ClaimsAuthServiceBehavior());

       var binding = new WebHttpBinding();
       _host.AddServiceEndpoint(typeof(IMonkeyShavingService), binding, "");

       _host.Open();

       Console.WriteLine("Press any key to exit.");
       Console.ReadKey();
 }

7. Last but not least, Use (this is a sample service method that restricts access to certain users)

 public Monkey PutMonkeyInShaver(Monkey monkey)
 {
      //Only authenticated users can add monkeys to the shaver
      if (CurrentUser == null)
      {
       SetStatusCode(HttpStatusCode.Forbidden,
                     "Only authenticated users can put monkeys in the shaver.");
       return null;
      }

      _monkeys.Add(monkey);
      ShaveMonkey(monkey);
      return monkey;
 }

 private IClaimsPrincipal CurrentUser
 {
     get { return Thread.CurrentPrincipal as IClaimsPrincipal; }
 }

It works, but…

Our ultimate solution does not extend or take advantage of any of the claims based security features built into WCF. While it may be possible to do so, it wasn’t immediately obvious to us how to go about it, so the solution presented here handles authorization out of band from the built in WCF authorization mechanisms.

As you may have guessed, I am NOT a WCF expert. That means that the approach outlined here could very well be a cheap hack for a problem solvable in a much more elegant way. If by some chance you happen across this post and know that to be the case, I’d love to hear your thoughts on the subject :) I wasn’t able to find any guidance during my own research that hinted at a more appropriate approach to solving this problem, but that certainly doesn’t mean one doesn’t exist.

About the Sample Application

The sample application can be downloaded here and includes a complete, end to end REST API implemented in WCF. It includes separate DLL’s to represent the Service, the Contracts, the Client, a Service Host and a Utility DLL that contains shared authentication and authorization code. To get the most from the sample you should run the Service Consumer project, a Windows Forms application that allows you to invoke various operations of the API while impersonating users with various roles. In addition to demonstrating a possible approach to flowing a claims-based security token through a REST API, the sample demonstrates a fully functional, RESTful WCF service, which may be useful to you in its own right.

Here is a screen shot of the sample Windows Forms service client:

What’s Next

In the future I will be enhancing the sample to demonstrate our approach to defining authorization policies that operate against a set of claims using our Simple Expression Evaluator project, currently on CodePlex. This technique will show how a simple but powerful and flexible claims-aware rules engine can easily be constructed using any expression evaluator and a set of claims.

Flowing Identity from a Client to a Service when using RESTful WCF Part 1 – The Problem

The digital representation (or identity) of users accessing connected applications will be increasingly modeled using the the concept of Claims. If you’re workingimage with SOAP based web services then the problem of how to implement claims based access control into your WCF services is is a fully solved problem. Whether or not you are using the new Zermatt framework or the claims based identity support in the System.IdentityModel namespace there exists plenty of guidance, available on the web and in books, to help you get everything wired together in a predetermined way. If you’re writing a REST API, however, things aren’t so simple.

SOAP vs REST in WCF – who cares? A service is a service, right?

All of the claims based security support in WCF relies on SOAP envelope headers to transmit a user’s claims from the service consumer to the service. This is to be expected, as several WS-* specs play an important role in WCF’s security support. As a result, if you are using a SOAPless WCF binding such as the RESTful WebHttpBinding, the best you can get for free is transport level security. That means you’re pretty much limited to transmitting authentication credentials, such as a username/password pair (via Http Basic Auth) , a Certificate, etc. If you have a security token containing claims you’d like to pass along, such as a SAML token, it isn’t immediately obvious how to flow that token from the service consumer to the service provider.

Hey, SOAP doesn’t have a patent on Envelopes!

In a RESTful API there is no “envelope” inherent in the message payload itself like there is with SOAP messages.  Indeed, when retrieving data from a RESTful service, there is no message payload at all. The entire scope of a GET request is communicated via the URL. Unlike SOAP, however, the transport protocol you will be using with REST is not a configurable, deploy-time variable. REST operates over HTTP by definition, and the HTTP protocol specifies its own message envelope that supports message headers. These are just the standard, everyday HTTP headers you already know and love. Therefore, we decided the best place for a security token to be stashed when working with RESTful WCF was in a custom HTTP header.

Where do you get a security token from in the first place?

Actually, I’m not going to go into how you go about authenticating a user and obtaining a claim-laden security token (usually a signed, encrypted SAML token). Zermatt should be able to help out with this (see this post for how), and there are also inexpensive .NET libraries you can buy that will abstract away the yucky cryptography/SAML aspects of creating and consuming a proper token. You can even leave these details until the Last Responsible Moment if you want, and, like we are doing, stub out the process of building or obtaining a proper interoperable token and temporarily substitute a simple plain text, character-delimited or XML serialized list of claims to getting everything working and tested and then plug in the gory details later in the process when you’ve selected a vendor/platform/framework as your Security Token Service (STS). For more info on building or buying an STS, see here and here.

The problem distilled

So that leaves us with only a single problem: how do we send a custom HTTP Header containing the logged in users security token with each service request without giving up the convenience of runtime-generated proxies via the WebHttpChannelFactory? Ok, there is another (small) part to the problem: how do we read this custom header on the service side of the wire early enough in the WCF lifecycle so we can unpack the embedded claims and make them available to the service implementation for making authorization decisions?

WCF Extensibility to the rescue!

The specifics of the solution, and code samples, will be presented in the next post.

Identity’s new Identity – Part 4, The Links (or, Identity for .NET Hyperlink Acupuncture)

August 29, 2008

image This is the final post in a series of posts about managing digital identity in a .NET world. See Part 1, Part 2 and Part 3 for background and some discussion.

The Foundations

The Laws of Identity
Kim Cameron’s Laws of Identity – setting the rules for the Identity Metasystem

Introducing the Identity Metasystem
Kim Cameron introduces the Identity Metasystem

The Identity Metasystem
Kim Cameron’s white paper on the Identity Metasystem

The Architecture Journal – Issue 16 – Identity and Access
A whole issue of the Architecture Journal dedicated just to Identity. Very good issue. The PDF of the issue is here.

Digital Identity for .NET Applications: A Technology Overview
This is an in depth examination of digital identity, claims, tokens SAML and the lot, in the .net world by Dave Chappell

Zermatt Links

Zermatt Whitepaper for Developer’s
A developer oriented overview of Zermatt, its architecture and its capabilities. The first thing you should read if you are interested in Zermatt.

A New .NET Identity Class
This is a general purpose article examining the new Zermatt class library.

Implementing an Identity Provider and Relying Party using ASP.NET MVC
An end to end examination of using Zermatt to create an IP and an RP using MVC.

Using Zermatt’s claims model on WCF: ClaimsPrincipal.Current
A blog post describing how to set up Zermatt to work with WCF’s security model

Getting Down with Zermatt
A nice, brief introduction to getting up and running with the Zermatt SDK

A Visual Studio Template for Zermatt Powered Websites
Well ain’t that cool…

Steve Maine (of the MVC world) introduces Zermatt…

Zermatt: Using Forms Authentication in a Passive STS
Setting up Zermatt as a non-Windows Auth based STS

Create a Basic STS Using Zermatt
Another good article on creating an STS using Zermatt

Identity Oriented Blogs

Kim Cameron’s Identity Blog
This is THE blog for keeping abreast of the identity landscape. Kim Cameron proposed the Laws of Identity which sets up the rules for the Identity Metasystem. A very interesting blog by an identity luminary.

Least Privelege
This blog deals with many things WCF and Identity related, but is an excellent resource if you have any interest in this topic at all.

Vibro.NET
This blog is listed on the MS Connect site for Zermatt as one of two blogs to follow for Zermatt info. The other is Kim Cameron’s blog.

Claim’s Based Security in WCF

Building a Claims Based Security Model in WCF, and Part 2
This is a set of articles by Michele Leroux Bustamante describing how to set up a claims based security model in good old legacy WCF (that is, WCF prior to Zermatt).

Misc Links

Creating an STS in .NET
This is a general purpose MSDN article on creating an STS. Really it’s a short description of signing tokens and setting up a SOAP response.

Introducing InfoCard (via CardSpace)
Dave Chapell talks about CardSpace

Identity’s new Identity – Part 3, The Technology

The face of Identity is changing, as I’ve discussed in agonizing depth in Part 1 and Part 2 of this monologue. So hurrah for the Identity Metasystem, Identity  imageFederation and all that swinging jazz, but now what? Well, if you’re in the business of designing and building software systems and you want your applications to be able to run with the jet set you’ll probably want to be thinking about how an application should go about implementing support for externalized authentication, claims based authorization and the like. In many cases you may also want to buy or build your own Identity Provider / STS so you can have the benefits of federated identity but still keep the keys to the castle inside your organization.

If you’re on the .NET Platform, and therefore on the Microsoft platform, you have a few options available to you.

Commercial Turn-Key Solutions

Although I’m only aware of one vendor in this space, Ping Identity, I imagine there are others. Buying a turnkey solution will probably offer the least touch, most expedient route to enabling new and existing applications with the capabilities to participate in the Identity Metasystem or any other identity system. I say turn-key, but of course some integration is required. Ping Identity offers products like Ping Federate, offer highly polished, low friction components that will allow your existing IT components to play ball with partners using any of a number of federation protocols (SAML 1.1, 2.0. + more) and they have .NET client and server libraries and even offer a free trial of their stuff. If you know what you want and just want to get started, I’d recommend looking there first.

Active Directory Federation Services (ADFS)

Active Directory Federation Services (ADFS) is a component that is part of Windows Server 2003, so it doesn’t add any cost. ADFS provides a framework on which you can build an STS that integrates Active Directory with external applications. I looked closely at this product at one point, and from my perspective it seemed a bit complex. Internet searches revealed that implementation of ADFS isn’t a proverbial walk in the park. As ADFS is going to be re-implemented using Microsoft’s latest and greatest identity platform called Zermatt, which I’ll talk about in a moment, you may way to hold your horses on a ADFS implementation.

WCF Claims Based Security – the System.IdentityModel Namespace

WCF has extensive support for claims based security built into it, and it is documented very well in many books and online articles, blog posts, etc. Claims based authorization in WCF (although not limited to WCF) is in the System.IdentityModel namespace. Unfortunately, however, it seems that Microsoft’s newest, shiniest identity effort (Zermatt) is not backwards compatible with System.IdentityModel. In the discussion forum on the Connect Web site for Zermatt they even called systems based on the WCF 3.0 model Legacy. So…I’m not sure building new applications using System.IdentityModel would be very future proof.

Zermatt = Identity.NET

Microsoft has released to public beta a brand new framework code named Zermatt. Zermatt is billed as providing the .NET component libraries required to easily add robust claims based authorization and interoperable identity federation capabilities to your .NET based software, as well as making it a boilerplate experience to put together a custom Security Token Service, which is really quite something. Building an STS has not historically been a simple undertaking on the MS Platform thus far. There is a very good white paper on Zermatt which goes into some depth about all of these topics that I highly recommend reading. The big downer, though, is that the Zermatt SDK won’t install on XP. It requires Vista or a Windows Server OS. However, the Zermatt SDK looks so enticing, and promises to deliver powerful digital identity management to our software with such little effort, that it may be the carrot that spurs us to upgrade our development environment from XP to Vista (or Server 2008). One way or the other Zermatt is the future for identity management on the Microsoft platform, so if you don’t take a look at it now, you’ll be taking a look eventually.

Information Cards (eg CardSpace)

I didn’t end up getting into this aspect of the identity puzzle, but one of the major issues with the current state of identity management is the proliferation of passwords and the general weakness of the username/password concept itself. Identity Selectors were invented to solve this problem, and provide a highly secure, certificate based approach to authentication that supports the claims based model and eliminates the need for using usernames and passwords entirely ( as long as all the systems you use accept cards ). Information Card’s (such as those provided by the CardSpace technology) can be issued by Identity Providers and accepted by Relying Parties. Alternatively, self issued Identity Card’s can be directly accepted by relying parties in lieu of a username/password. You can read about CardSpace here.

OpenID, OAuth

On the consumer end of things, OpenID provides an open standard that can be used by public facing web sites to allow users to centralize their identity management. Similar in concept to the original Windows Passport concept (you can still use Live ID, the Passport successor, if you like) Open ID and similar standards allow you to design your application to delegate authentication of users to third party servers who you elect to trust. This is a gift to your users because they can manage a much reduced quantity of digital identities, have one place to manage username / passwords and change them if they become compromised, and more or less maintain more control over their online information. OAuth is a similarly open standard for centralizing authorization to open APIs and other web services to allow applications to create mash-ups of users data without having to ask the user for credentials for each service they wish to use in the mashup. I don’t work on consumer software, so my knowledge of these technologies is limited, but if you are working on public facing software OpenID and OAuth are probably where you want to put the tip of the Identity chisel.

So there you have it folks. Let me know if I’ve forgotten any major pieces of the puzzle. There wasn’t room in this post for the list of links, so I’ll follow up shortly with those.

Identity’s new Identity – Part 2, The Lay of the Land

August 28, 2008

Kill the User! Or, at least the Users table. As I explained in Part 1,  you’ll have a better chance of going to heaven if you do. Inimage this post I’m going to offer my nearly-layman’s understanding of the Identity landscape as it seems to be  unfolding in the industry. The next post will be a link post, so if you tire of my rambling and ceaseless blah blah blah you can go read about some of this stuff from qualified experts.

So the question that is on everyone’s lips is this: if it no longer makes sense for each individual application to maintain its own catalog of users then what is the alternative? If you don’t maintain a list of users and what roles they have, how will you determine what they should or shouldn’t be able to do? If you don’t examine their usernames and passwords, how can you be sure they are who they say they are? Or, maybe it is time to abandon access control in computer systems entirely, issue in a new age of freedom and love, a sort of modern day hippie revolution? No?

Then welcome to the Identity Metasystem. The Identity Metasystem is an architectural arrangement that classifies Identity related activities into three distinct roles and specifies the interoperable protocols (all smelling strongly of SOAP and WS-*) available to each role when conducting Identity related business with each other. These three roles are:

  1. Identity Provider (IP)
  2. Relying Party (RP)
  3. Subject

The basic idea is that if your system is participating in the Identity Metasystem, as all good, socially responsible systems strongly consider doing, you agree to relinquish control of authenticating your users and delegate that task to specialized systems, or Identity Providers (IP). Systems giving up their Users table that are now relying on an IP to authenticate their users are Relying Parties (RP). The users actually being authenticated by an IP in order to gain access to an RP are Subjects. To make all this a little more clear, I offer a parable:

A Subject walks into an RP and says ‘Give me a pint of your strongest data.’ The RP looks suspiciously at the Subject and says ‘wait just a minute buddy, I don’t have the foggiest idea who you are…’  The Subject pulls out his username and password and holds them out to the RP, who waves his hands in front of his face and shouts ‘Don’t show them to me! I don’t want to see your freaking password, show your credentials to the IP! So the Subject turns to the IP sitting at the next barstool and shows him his username and password. The IP examines the Subject’s credentials, sees they are valid, and initiates a complex series of hand signals that look a lot like gang signs. The RP compares the hand signals to a set of approved hand signals in a little book he keeps behind the bar and verifies that he trusts this particular IP. Satisfied, he serves the Subject his data.

To make this work the various roles in the Identity Metasystem  get on with each other by following the Laws of Identity as formulated by Kim Cameron, an architect at Microsoft and an Identity luminary. Additionally, all Identity funny business is transacted using interoperable, WS-* based protocols like WS-Trust and WS-Federation, allowing complete freedom in platform and technology choices when building or migrating systems to participate in this New World Order.

Claims Based Authorization

Many, if not most, existing systems rely on Role Based Authorization to authorize user activity. Role Based Authorization is often very specific to an individual system – the system stores what roles a user has, and looks up those roles when a user logs in to make decisions about what that user can do. This is all good and well, but it isn’t exactly practical in a system that has outsourced its authentication to an IP (even if the IP is controlled by the same organization as the system in question) because individual software systems don’t own their users in the Identity Metasystem – the IP’s maintain user records on behalf of users of multiple systems.

The solution is for the IP’s to maintain what roles a user has, and those roles will travel from system to system along with the user. And instead of just having a flat list of roles, users travel around with all kinds of useful information that might be useful to RP’s wanting to make authorization decisions, like a users age or how long an employee has been with the company. These bits of information are known as Claims. A Claim is really nothing but a name value pair, but like ID cards in a person’s wallet, all of this identifying information is always with the user. At any time a Relying Party can examine the authenticated user’s set of claims to make an authorization decision. In the end this way of working is infinitely more  flexible and sociable than the old way.

From a technology perspective, claims are represented and transmitted as encrypted, signed interoperable tokens (usually SAML – Security Access Markup Language) that are issued upon request by the Security Token Service (STS) of an IP and presented to a Subject to give to an RP. Alternatively tokens may be provided directly to the RP once the user has been authenticated.

I think that is more than enough for now. Next post I will talk about specific technologies in the Microsoft world that can make building this kind of functionality into your own applications pleasantly easy, as well as give a very brief overview of Identity Selectors, such as Windows Card Space, and where that technology fits into this picture. And of course the usual collection of links. Next: Part 3 and Part 4.

Identity’s new Identity – Part 1, a Birds Eye View

August 27, 2008

Identity is a big topic now-a-days. Not the identity you go backpacking across Europe to discover, but the kind of identity that a computer system uses to image determine whether to allow itself to be queried or manipulated by one incoming connection as opposed to another. (Sounds kind of dirty, doesn’t it?)

As the World Wide Web continues its imperialistic drive to connect every electronic device on the planet to every other in Borg-like fashion (if you’ll permit me to lapse into slobbering geekatude) the momentum behind technology focused on Digital Identity is finally starting to catch up.

What’s wrong with digital identity the way that it is? Well, while you can access any of a billion different computer systems from your cell phone in the middle of a swamp in the Australian outback, you’ll still have to scrunch up your eyes and punch in half a dozen username-password combinations on your tiny keyboard as you move from system to system – a strange contrast. On the one hand almost godlike connectivity, bordering on omnipotence, and on the other a sad comedy of "forgot-my-password" links and identity theft. Power and Stupidity – fused together to form something as irritating as it is dangerous (see figure 1 to the right).

Affectionately known as  password hell, this kind of arrangement has implications far more sinister than simply being tremendously annoying. The cost to IT organizations and help-desks trying to support this unsupportable user-experience nightmare is huge, system integration is made much more difficult and expensive than it would otherwise need to be, and the privacy and security implications of your sensitive user information and login credentials being stored in n number of individual databases across the Internet protected by varying and unpredictable degrees of security are frightening. Then there’s just the good old fashioned loss of productivity that results from the high friction computing experience caused by the need for overly complex identity management.

So the 30,000 foot view of the root of the problem is this: most independent software applications maintain ownership of a proprietary user directory to authenticate and authorize access to themselves. (Applications that live entirely inside the corporate firewall will often rely on a shared infrastructure level directory service to synchronize or share user identity between internal applications, but this is not always the case for every application, and as Software as a Service and Cloud Computing begin to conquer the universe, the number of applications that have the luxury of living entirely within the firewall will get smaller and the number of applications living in the wild will get larger and larger. This is unavoidable.)

The 30,000 foot view of the solution is this: most independent software applications will need to give up the snuggly comfort of proprietary, internal user directories and delegate responsibility for authenticating and identifying their users to specialized, centralized systems designed for exactly that and nothing else.

Such externalized authentication systems are often referred to as Identity Providers and are implemented via a kind of server called a Secure Token Server (STS). The concept of a software application accepting authentication decisions made by a separate (though trusted) system is called Identity Federation.

Software developers, by and large, are control freaks, so this solution may be difficult for many of us to accept. We may clutch our Users table to our chests and scream "Don’t take my baby!" in a Southern accent, but in the end it won’t do us any good. As momentum behind identity federation increases both businesses and end users alike will quickly lose what is left of their rapidly deteriorating patience with any software application that insists on authenticating them personally.

Fortunately the technology part of the problem is essentially solved. In Part 2, Part 3 and Part 4 I’ll explore some of this technology, particularly the kind of stuff likely to be useful to those working with .NET. I’ll also take a closer look at the long-overdue replacement for Role Based Access Control: Claims Based Access Control, a style of determining what permissions a user has in a system that goes hand in hand with modern implementations of identity federation and the standards and protocols that enable it (such as SAML). Claims Based authorization is more powerful and more flexible than role based authorization, and so provides significant advantages even outside the context of identity federation.

Identity is no longer something that can be a foregone conclusion in the design of a new application. The old, loyal Users table with her gout-filled username and password columns is showing her age. The old girl is having trouble coping in a hyper-connected world. Time to tell the doc, "Pull the plug! For gods sake man, put her out of her misery! That just ain’t no kind of livin’!" And then it’s time to try something new.

OpenID – Using your own domain as your OpenID, without hosting a OpenID Server

April 18, 2008

If you haven’t heard about OpenID yet, you will. It is an identity federation concept like Passport was meant to be, but it is an open specification, not an implementation. Therefore anyone is free to create and manage an OpenID service and provide OpenID’s. The idea is that if you get an OpenID from some provider, it doesn’t really matter, and the any web application (or windows application for that matter) that supports OpenID can accept your OpenId credentials instead of username / password specific to that application. Eventually it will reduce the number of places you have to maintain credentials. Coupled with Information Cards, it could be a really great thing. We will probably try to support it in our tools soon. This also provides a link to a comparison of various OpenID providers.

myopenidlogo.jpg

The article is here

 

Here is a very nice, user friendly discussion of Open ID, it’s relation to CardSpace, in the usual Scott Hanselman style…

http://feeds.feedburner.com/~r/ScottHanselman/~3/280609393/TheWeeklySourceCode25OpenIDEdition.aspx