Welcome to MSDN Blogs Sign in | Join | Help

RIA Services and WIF – Part II

As promised in my previous post, here’s the second part of my findings playing with WIF and RIA Services beta. This time, I used the HRApp sample available here.

The initial steps are essentially the same I described before:

1- Installed the sample and make sure it runs

2- Ran “FedUtil” which:

a- Created an STS and added it to the solution.

b- Change the application web.config with necessary settings for WIF (added modules, added federation information, etc)

3- F5 and voila. It just works:

image

 

image

 

My next step was to make a few modifications to:

 

1- Transfer “Roles” information to the UI. I  wanted that information to be available on the Silverlight app and eventually drive UI behavior based on that.

2- Add finer grained Authorization logic to the service. For example, I wanted not only authenticated users to approve sabbaticals, but only those who are “Managers”

 

More good news! It turns out this is very easy to implement:

For #1, I simply used the same technique I used in my original prototype (adding a RoleProvider that inspects the Role claims):

 

public override string[] GetRolesForUser(string username)
{
    var id = HttpContext.Current.User.Identity as IClaimsIdentity;
    return (from c in id.Claims
            where c.ClaimType == ClaimTypes.Role
            select c.Value).ToArray();
}

 

Note: in RIA Services beta, “RiaContext” has been replaced by “WebContext”. So instead of using: RiaContext.Current.User.Roles you use: WebContext.Current.User.Roles.

 

The second requirement is even easier. RIA Services ships with a built in attribute you can use to decorate a method in your service: RequiresRoleAttribute.

So, I simply replaced “RequiresAuthentication” in the original sample for:

 

[RequiresRole("Manager")]
public void ApproveSabbatical(Employee current)
{
    // Start custom workflow here
    if (current.EntityState == EntityState.Detached)
    {
        this.ObjectContext.Attach(current);
    }
    current.CurrentFlag = false;
}

 

The STS that FedUtil created for me, adds this claim to the token when I authenticate (see inside GetOutputIdentityClaims method in CustomSecurityTokenService.cs):

    ClaimsIdentity outputIdentity = new ClaimsIdentity();

    // Issue custom claims.
    // TODO: Change the claims below to issue custom claims required by your application.
    // Update the application's configuration file too to reflect new claims requirement.

    outputIdentity.Claims.Add( new Claim( System.IdentityModel.Claims.ClaimTypes.Name, principal.Identity.Name ) );
    outputIdentity.Claims.Add( new Claim( ClaimTypes.Role, "Manager" ) );

 

If now I change “Manager” for “Employee”, RIA will raise an “Access Denied” exception:

image

 

This works for Roles, but what if you wanted to express access rules based on other claim types (repeat after me: Roles are Claims, Claims are not Roles)? Let’s say, you have to be in a “Manager” role working in the “HR” group to approve sabbaticals: 

 

[RequiresRole("Manager")]
[RequiresGroupMembership("HR")]
public void ApproveSabbatical(Employee current)

All you need to do is create a RequiresGroupMembershipAttribute and inspect the claim set for presence of a claim of type “Group” with value “HR”:

 

public class RequiresGroupMembershipAttribute : AuthorizationAttribute
{
    public string requiredGroup;
 
    public RequiresGroupMembershipAttribute(string group)
    {
        this.requiredGroup = group;
    }

    public override bool Authorize(IPrincipal principal)
    {
        var identity = ((principal as IClaimsPrincipal).Identity as IClaimsIdentity);
        return identity.Claims.Exists(c => c.ClaimType == "http://hrapp/Org/Groups" && 
                                                 c.Value == requiredGroup);
        
    }
}

 

and add the claim to the STS:

outputIdentity.Claims.Add( new Claim( System.IdentityModel.Claims.ClaimTypes.Name, principal.Identity.Name ) );
outputIdentity.Claims.Add( new Claim( ClaimTypes.Role, "Manager" ) );
outputIdentity.Claims.Add( new Claim( "http://hrapp/Org/Groups", "HR") );

 

Of course you could refactor the above to accept any claims, not just Groups or Roles. Something like:

 

public class RequiresClaimAttribute : AuthorizationAttribute
{
    private string requiredClaimType;
    private string requiredClaimValue; 

    public RequiresClaimAttribute(string claimType, string value)
    {
        this.requiredClaimType = claimType;
        this.requiredClaimValue = value;
    }

    public override bool Authorize(IPrincipal principal)
    {
        var identity = ((principal as ClaimsPrincipal).Identity as IClaimsIdentity);
        return identity.Claims.Exists(c => c.ClaimType == requiredClaimType && 
                                           c.Value == requiredClaimValue);
    }
}

 

and

public class RequiresGroupMembershipAttribute : RequiresClaimAttribute
{
    public RequiresGroupMembershipAttribute(string group) : base("http://hrapp/Org/Groups", group)
    {
    }
}

 

Then, you could write:

[RequiresRole("Manager")]
[RequiresGroupMembership("HR")]
[RequiresClaim("http://hrapp/Location", "UK")]
public void ApproveSabbatical(Employee current)
  
 

Caveats: this is sample code, so I’ve not invested much in error handling, etc. This is “as is”.

Updated RIA and WIF samples – Part I

Some time ago, I put together a simple demo integrating WIF in RIA Services. Now RIA is a Beta and there’s a lot of cool stuff in there. The good news from an identity perspective is that it just works :-).

I’ve been playing a little bit with a couple of new samples and with the previous (updated) HRApp. The first one is the “CyclingClassifieds” you can download from here.

The identity  architecture of the application is simple enough for a first exploration. Out of the box, it is configured for Windows integrated security, so if you run the sample it will simply recognize the user you are logged in as in your network. The app has an “auto-provisioning” feature that automatically registers external users into the application. There’s a stored procedure that will try to locate the user name in the database (Users table), and if it is not found, it will simply add a new record:

 

image

 

“Claims-enabling” this app is simple, because authentication has already been factored out. The app as it is designed today is not responsible for identifying its users. Something else does it for the application (Windows).

Steps:

1- First you need to install WIF and WIF SDK. We want the SDK to use the Visual Studio integrated tools.

2- Make sure the app runs before any changes. One line of code you will need to change is in the GetUserId method of the CyclingClassifiedsService:

image

It is well explained in the comments in there.

3- Next step is to change the configuration and “claims enable” the app. Right click on the web site and select “Add STS Reference”:

clip_image002

4- This will start FedUtil wizard:

clip_image004

Because this app is very simple and only requires authentication really (there are no roles or any other claims that will be used here), simply select all defaults.

On the second screen, you have multiple options on which Issuer to use. The Issuer is the system that will return Security Tokens (with all claims) to the application. The application will be configured to trust this Issuer. I selected “Create a new STS project in the current solution”, because I wanted the sample to remain self-contained. Of course you could have chosen a real issuer somewhere else (e.g. your ADFS, an existing development Issuer, etc).

clip_image006

5- After all this is done, the solution will have an additional project. There’s some boilerplate code, but the heart of the issuer is the class CustomSecurityTokenService:

clip_image008

Fedutil will create a template with some default claims (search for GetOutputClaimsIdentity method). This is one place :

clip_image010

The web.config file will also be updated with new configuration settings. Very similar to what I explained in the previous post. (e.g. WIF modules, etc)

 

6- Compile and run the app. The first screen you will see is the Issuer login page:

 

image

No password is really verified because this is a “fake” Issuer. Clicking submit, will initiate the process of issuing a token (essentially all under the GetOutputClaimsIdentity method) and redirection to the original site where the normal RIA app life cycle starts. A breakpoint in the AuthorizationService file will reveal “WIF magic” happening:

image

Notice that the type of the user identity is “ClaimsIdentity”.

Finally:

 

image

 

if you browse the contents of the User table you should now find a record for “Adam Carter” in it.

I will now do the same for the HRApp and post my findings.

WIF is RTM

WIF

Windows Identity Foundation is here! Congrats to my colleagues shipping great Framework.

http://msdn.microsoft.com/en-us/evalcenter/dd440951.aspx

Claims based Identity Guide – New release and PDC goodness

New updated chapters & samples are posted on CodePlex. The samples are all updated for WIF RC and include new scenarios and technologies (e.g. web services with WCF and web sites with MVC).

If you are going to PDC, lot’s of interesting things are happening there. Of all things, you will have a chance to see (and speak) to the faces behind the blogs: Vittorio Bertocci, Matias Woloski, Keith Brown.

We have printed a limited amount of “preview” copies of the Guide. You can get them at Pluralsight’s (#441), patterns & practices and Identity booths.

In addition to the “previews”, Pluralsight is giving away a ton of great content: (3) Zune HDs loaded with Pluralsight On-Demand! content, Pluralsight Cloud tag t-shirts & 1-week subscriptions to Pluralsight On-Demand!. And, if let them know, they will be hosting their first-ever annual Pluralsight Customer Appreciation Party. Invite required for entrance.

 

Sessions you don’t want to miss:

 

Windows Identity Foundation Overview

Vittorio Bertocci in 403AB on Wednesday at 11:30 AM

Hear how Windows Identity Foundation makes advanced identity capabilities and open standards first class citizens in the Microsoft .NET Framework. Learn how the Claims Based access model integrates …

 

Claims-Based Identity

Keith Brown in 309 on Thursday at 11:30 AM

Are you interested in or currently building out applications that use claims-based identity? Come join others who are also working on similar systems and discuss your successes and pain points with …

 

Software + Services Identity Roadmap Update

Kim Cameron, Dmitry Sotnikov in Petree Hall D on Tuesday at 11:00 AM

At PDC 2008, Microsoft unveiled a comprehensive offering of identity software and services, based on the industry standard claims-based architecture, and designed to address the rapidly growing …

 

Enabling Single Sign-On to Windows Azure Applications

Hervey Wilson in 403AB on Wednesday at 3:15 PM

Learn how the Windows Identity Foundation, Active Directory Federation Services 2.0, and the claims-based architecture can be used to provide a uniform programming model for identity and single …

 

How Microsoft SharePoint 2010 was Built with the Windows Identity Foundation

Sesha Mani in 403AB on Thursday at 3:00 PM

Explore how SharePoint 2010 has undergone a shift in identity and access control by adopting the claims-based object model offered by Windows Identity Foundation (WIF). Learn how SharePoint 2010 …

 

Leveraging and Extending Microsoft SharePoint Server 2010 Identity Features

Venky Veeraraghavan in 403AB on Tuesday at 3:00 PM

Get an architectural and programmatic overview of Claims based Identity implemented in SharePoint 2010 including how identity is dealt with at Sign-in and for service calls both within SharePoint and …

 

Have a great time in L.A.!

Claims based Identity & Access Control Guide – Updated drafts & samples available

Yesterday, we uploaded a new release of the Guide and the samples. You can download the content from here. (Note: if you downloaded them yesterday, you might want to check again. We mistakenly uploaded the samples with no docs. It is fixed now).

You’ll find:

  • Updated introduction & WebSSO chapters, incorporating quite a bit of feedback
  • New updated samples, including scenario #2 (Federation with Partners). This is inspired in this article I wrote some time ago. 

Getting started with the samples:

Just download the zip file, expand somewhere in your disk. There’s a readme.htm with some very basic instructions and prerequisites.You’ll have to run StartHere.cmd batch file with elevated privileges (this essentially installs necessary certificates). Open the solution (as admin), compile and run.

Prerequisites haven’t changed:

  • Visual Studio 2008
  • IIS (for HTTPS)
  • WIF

There are 2 scenarios folders now: scenario #1 (WebSSO), which is the same we published a couple of weeks ago. Then there’s the new one that shows federation between Adatum’s a-Order and Litware.

The first time you open Visual Studio, it will create some new web sites for you.It might happen that those websites already exist from previous drop, you might want to delete them beforehand if you expand the files in a different location.

Make sure the default app is “Litware Portal”:

image

This is the launching point for the application from Litware’s perspective.

The major changes from the code in Scenario #1 is that now Adatum.IdentityProvider has been extended to other things, namely manage the trust relationship between Adatum and Litware. That’s why we now call it Adatum.Issuer. This new functionality includes transforming claims issued by Litware into claims understood by a-Order. All this is happening in the FederationSecurityTokenService class. 

image

Adatum.Issuer is a “mock” STS and its implementation is no more and no less than what is strictly needed for the sample to work. In the real world you would replace it, as we did in our test Lab, with a real/production quality issuer such as ADFS v2.

The transformation rules in our mock STS are trivial and are all implemented in the GetOutputClaimsIdentity method override:

protected override IClaimsIdentity GetOutputClaimsIdentity(IClaimsPrincipal principal, RequestSecurityToken request, Scope scope)
        {
            var outputIdentity = new ClaimsIdentity();

            if (null == principal)
            {
                throw new InvalidRequestException("The caller's principal is null.");
            }

            var claimsIdentity = (ClaimsIdentity) principal.Identity;
            var issuer = claimsIdentity.Claims.First().Issuer;

            switch (issuer)
            {
                case "litware":
                    ProcessClaimsFromLitwareIssuer(claimsIdentity, outputIdentity);
                    break;
                default:
                    throw new InvalidOperationException("Issuer not trusted.");
            }

            return outputIdentity;
        }

 

The samples contain a number of annotations and hints here and there to explain what is happening. Make sure you hover with the mouse over this little information icon to get extra context:

image

This is still under development of course, so expect quite some changes. But we hope you’ll find it useful anyway. Feedback is very much welcome as always.

Very special thanks to the following people for their extensive feedback and suggestions for this Guide:

Mario Szpuszta, Pablo Cibraro, Travis Spencer, Mario Fontana, Jason Hogg, Michele Leroux Bustamante, Pedro Felix.

RIA Services and Windows Identity Foundation – Claims enabling a RIA application

Recently a Customer asked me if an application using RIA Services could use WIF. I’m fairly new to RIA Services so I didn’t know the answer right away, however I suspected the integration should not be too hard, so I spend a couple of days spiking a solution.

The good news: it just works!     

What I did:

I took one of the samples available from the RIA Services website (HRApp, you can download it here: http://code.msdn.microsoft.com/RiaServices, more specifically: http://code.msdn.microsoft.com/RiaServices/Release/ProjectReleases.aspx?ReleaseId=2387 )

After installing and verifying everything worked, I “claims enabled” it by running “FedUtil.exe”. I configured it to point to Adatum Issuer (exactly the same you can download from the Guide CodePlex site: http://claimsid.codeplex.com).

As expected, FedUtil changed a few setting in the app config file to enable claims: WIF modules were registered and the relationship with Adatum Issuer was established:

clip_image001

clip_image002

I then ran the application again and I was gladly surprised to be first redirected to the Issuer for authentication:

clip_image003

If you have installed the Guide samples, you are probably familiar with this screen and you know that it will issue a set of claims for a user “Mary” that includes 2 roles “Orders approvers”, “Employees”. When I click on “continue button”, claims are issued and sent to the RIA application where now I’m authenticated and recognized:

clip_image004

If you break into the application (server side) and inspect the User object from the HttpContext you’ll notice there’s a “ClaimsIdentity” and you have access of course to the claims collection, etc. That is part of the “magic” performed by WIF modules:

clip_image005

On the Silverlight side, you can see that now the User object in the RiaContext also reflects the content obtained in the server side. This is thanks to some of the magic wiring RIA Services does for us:

clip_image006

RIA Services out of the box implementations rely on ASP.NET infrastructure. I didn’t want to change the sample app too much, so I created a very simple RoleProvider that would simply resolve GetRolesForUser through the ClaimsIdentity. Here’s the (only) method that I implemented from the RoleProvider base class:

public override string[] GetRolesForUser(string username)
{
    var id = HttpContext.Current.User.Identity as IClaimsIdentity;
    return (from c in id.Claims
            where c.ClaimType == ClaimTypes.Role
            select c.Value).ToArray();
}

 

Roles are enabled in the web.config:

<roleManager enabled="true" defaultProvider="GenevaRoles">
  <
providers>
    <
add name="GenevaRoles" type="HRApp.Web.GenevaRolesProvider, HRApp.Web"/>
  </
providers>
</
roleManager>

 

Of course, Roles are Claims, but not all Claims are roles. You could extend the RIA User object to hold whatever other information you want. So you could end up having any other profile data in the user object that comes from a Claim (e.g. the “Cost Center” claim that our Issuer gives us).

Many thanks to Erwin for his help.

Claims based Identity & Access Control Guide – Early drafts available

We finally have a CodePlex site for sharing early content with you all. Check the downloads section for:

  • A few intro chapters (some of the “theory”, technologies and protocols behind claims based identity)
  • The first scenario (roughly described in my post here, but better and nicer, and written in English :-))
  • The sample code for this first chapter

The first scenario is fairly basic. However, I think people with little previous experience with Claims will find this really useful. Those who are very experienced, will probably not find a lot of new content at this point.


Few things to highlight:

On the code:

We wanted to keep it very very simple. Right now the only pre-requisites are: IIS and Windows Identity Foundation (WIF). IIS is needed because some pieces of the samples require HTTPS. WIF is needed because, well…this is about claims right? All the rest is mocked or simulated.

We tried to minimize the amount of setup required, but there are a few steps that are needed (e.g. installing a certificate, enabling HTTPS). There’s a small script that explains what to do. But we added quite some checking and verification here and there to highlight if something is likely to fail due to a problem in the configuration.

The IIS web sites are created the first time you open the solution in Visual Studio. Running the samples you should see:

image

Wherever you see the little blue “i” icon, there will be a tip with further explanations.

Many things in the samples are simulated. For example, a-Order in the chapter is described as a Windows Authentication enabled app. We don’t want to mess-up with your AD or with your machine accounts & groups. Also, when we claims-enable an app we don’t want to require you to necessarily deploy ADFS. Therefore we included in the solution a “fake” Issuer to create the required claims. The Guide explains the differences between the real scenario and the simulation though; and steps to configure a real scenario.

Following a-Expense (Claims Aware), for example leads you to:

image

Notice the extra explanation. Generally, you will not see anything automagically happening. The intent is that everything not obvious will have a tips like this or an in-line comment. 

 

On the chapters:

The first three chapters are introductory and you will see a lot of TBDs and comments. All of this is, of course, work in progress; but we’d love your input.

The introduction chapters are mostly “theory”: background, context, terminology, etc. The fourth chapter is the first scenario: WebSSO. You will see callouts here and there from one of our four main characters in the book:

- Bharath, the Security Expert

- Jana, the Architect

- Poe, the Operations guy

- Markus, the Developer

The intent is to highlight specific points of views from each of these guys and enrich the guidance we want to provide.

Important note: these chapters are NOT formatted to the final layout. So, for example, the callouts will be on the margins in the final book. Please concentrate on the content and not on the format for now.

Hope you like it! Let us know what you think!

Exploring the Service Provider track – Fabrikam Shipping Part II (Solution)

Now that we presented the scenario & the requirements, let’s take a look at the solution.

What is conceptual solution we propose?

Fabrikam Shipping in the pre-Claims era:

This diagram shows Fabrikam Shipping today if used by Adatum (no claims, no federation):

image

You will see the usual suspects for a typical .NET web application. Furthermore, Fabrikam is using standard providers for authentication, authorization and profile. In this configuration, everyone in Adatum must use, of course, user name & passwords. The username is the handle associated with a role in the roles database, which drives application behavior (what you can do).

In the example, John from sales, can only Order New Shipments, but Peter from Customer Service, can Manage them.

 

Making Fabrikam Shipping Claims-Aware

What we want now, is Fabrikam to be claims aware and trust claims issued by Adatum. Claims issued by Adatum will be used for authentication and authorization. We also want to map Adatum internal roles to Fabrikam’s for authorization purposes: who will be a “Shipment Creator”? Who will be an “Administrator”? 

image

Let’s see how this would work:

  1. When John attempts to use FS for the first time (e.g. https://adatum.fabrikamshipping.com), because there’s no session established yet (John is un-authenticated from FS point of view) he will be redirected to Fabrikam’s Issuer (e.g. https://login.fabrikam.com). Fabrikam’s Issuer is trusted by the application.
  2. Again, John will be redirected to Adatum’s Issuer, because that is what Fabrikam’s Issuer trusts.
  3. If John uses a domain joined desktop, he’d already be authenticated in his network and will have a valid Kerberos token. This token is used by the Adatum’s Issuer to create Adatum’s claims: employee name, employee address, cost center, and department John works for.  

The process unwinds then:

  1. Adatum’s claims are sent back to Fabrikam’s Issuer, where they are transformed:

- Name, address and cost center are simply copied (no transformation)

- Other rules are applied that will result in a “role” claims to be issued (any of the valid roles FS understands)

More examples of mappings:

exists([issuer == "Adatum"]) => issue(type = "Role", value = "Shipment Creator");

Which can be interpreted as:

“Any employee from Adatum can create shipment orders”

 

c:[type == “http://schemas.xmlsoap.org/claims/Group”, value == "Shipments"] => issue(type = “Role”, value = “Shipment Manager”);

that would implement the rule:

“Any employee from Adatum in “Shipments” (indicated by group membership) department can manage shipment orders”

      2. After these transformation happens, John is finally directed back to the application with the transformed claims.

Adatum could issue Fabrikam’s specific claims, but we don’t want to pollute Adatum’s Issuer with Fabrikam specific concepts (like Fabrikam roles). Fabrikam will allow Adatum to issue any claims they want or can, and then will allow Adatum to configure the system to map these Adatum claims into Fabrikam claims.  

Fabrikam will do this for every new Customer using Fabrikam Shipping. Yet, their application will always understand the same set of claims: “Shipment Creator”, etc. FS stays decoupled.

 

Note 1:
This scenario is almost identical to IssueTracker. If you feel deja-vu, don’t be surprised. Only in IssueTracker, we used .NET Services ACS as the Service Provider (Fabrikam) Issuer.

Note 2:
This scenario is also similar (but not quite the same) to Adatum’s a-Order. Some key differences: Fabrikam is a multi-tenant system, probably with a provisioning experience, that a-Order lacked. This is because in our fictitious (but hopefully realistic) world, the Customer churn in Fabrikam Shipping is much higher than in a-Order. That is, we assume the frequency customers join and leave Fabrikam is higher. Thus, Fabrikam needs to automate this as much as possible. 

Note 3:
Yes, there will be another post with Adatum’s side of the story. But I’m sure by now you’ll guess what’s in there.

 

I’ll cover provisioning in the next post, as it has some interesting discussion points. But you can see some hints here.

Feedback very much welcome.

 

Post-post announcement:

We hope to have a some running code and much much polished chapters soon. We’ll probably upload those to a CodePlex site. Stay tuned!

Exploring the Service Provider track – First station: Fabrikam Shipping – Part I (the scenario & challenges)

Once again, thanks everybody that wrote us with reviews, feedback and suggestions! Please keep it coming! Also: we hope to have soon a CodePlex site where we can start sharing more. We are still working out some details.

As usual, the Disclaimer: this post and the next ones are early drafts to share with you the direction we are taking. They might (and I hope they will) change quite a bit in the actual Guide! We might end up not covering one of these scenarios in the book.

An additional disclaimer for this post: I wrote the whole scenario following the same template of the previous posts and it resulted in a very loooong article. So I divided it into two parts. This is Part I –> the scenario, the challenges and the requirements. Part II will be the solution.

An Ode to Simplification: there’s been quite some debate internally to this project as how to name things, especially “STS” vs. “Issuer” vs. “I-STS” vs. “R-STS” vs. “FP”, etc. Keith has started this on his blog some time ago. We definitely want to keep things simple. As simple as possible, but not simpler. For now we have settled on the term “Issuer”, independently of the logical role it takes part in. In simpler words: what we used to call “Identity Provider” is now an “Issuer”. What we called a “Federation provider” is also an “Issuer”.

Keith is writing a whole section of our book on “Jargon” and meaning of the different terms.

Credits: this scenario is largely inspired on Vittorio’s PDC demo. See here.

image

The themes for the first “Service Provider” scenario are:

  1. Identity in a SaaS application
  2. Federation with multiple Customers

There’s 1 variations in this scenario:

  1. Automating the on-boarding process

The Introduction

Fabrikam is a company that provides shipping services. As part of their offering, they have an application (Fabrikam ShippingFS) that allows its customers to create new shipping orders, track them, etc. Fabrikam Shipping is delivered as a service and runs in Fabrikam’s datacenter. Fabrikam Customers use a browser to access it.

FS is a fairly standard .NET web application: the web site is based on ASP.NET 3.5, the backend is SQL Server, etc. In the current version, users are required to authenticate using (guess what): username and password!!

Fabrikam uses ASP.NET standard providers for authentication (Membership), authorization (Roles provider) and personalization (Profile).

Fabrikam Shipping is also a multi-tenant application: the same instance of the app is used by many customers.

One sunny day in Seattle, they sign a great deal with a marquee Customer: Adatum Corp. And Adatum doesn’t like the username and password, because they are working hard to get rid of identity silos. They have 3 concerns:

  1. Usability for their employees. Lack of SSO, forgetting passwords, using sticky notes to remember them, etc.
  2. Maintenance costs:
    1. What happens if an employee forgets his or her corporate password? He will probably call Adatum’s IT help desk. What happens if they use FS and they forget its password? who should they call? Consider this:
      1. If they instruct employees to call Fabrikam’s help desk, there would be a special procedure for IT guys, would probably require training, etc.
      2. If they instruct employees to call Fabrikam directly, they would impact #1
    2. When a new employee is hired, he is already provisioned in Adatum’s systems. They don’t want special processes for FS.
  3. Liability:
    1. Adatum has authentication policies that are there for a reason. They also want to retail control on who has access to what (regardless of where that is deployed) and FS is no exception.
    2. If an employee leaves the company, he should not have access to FS anymore, effective immediately. If they used username / passwords, they could potentially access FS from other places, even if they are not an Adatum employee anymore.

Back to FS:

Access Control to FS is based on Roles. There are 3 roles:

  1. Shipment Creators”. Anyone in this role can create new orders.
  2. Shipment Managers”. Can create and modify existing shipment orders.
  3. Administrators”. Can configure the system (e.g. look and feel, shipping preferences, billing, etc).

FS also keeps profile information for users, to avoid repeatedly entering common information and preferences. More concretely, FS allows its users to store:

  1. Package Sender information (sender address)
  2. Cost Center information for billing

Fabrikam can open the bills to its Customers by Cost Center. With this, 2 employees from Adatum belonging to 2 different departments would get 2 different bills.

 

Key Requirements.

Adatum wants SSO for its employees.

Fabrikam wants to avoid storing configuration information about the shipment that can become stale later on (e.g. the package sender information).

Fabrikam wants to bill customers by Cost Center if they supply one.

Some assumptions:

  1. Adatum has an Issuer (see Scenario #1)
  2. Fabrikam can change anything in their application

We’ll look at the solution space in the next post.

Next station: Federation between Adatum & its Customers.

First things first: thanks everybody who wrote me about the first scenario article. I got quite some e-mail on it with great suggestions to improve, but in general it seems it resonates well with.

Disclaimer: this post and the next ones are early drafts to share with you the direction we are taking. They might (and I hope they will) change quite a bit in the actual Guide! We might end up not covering one of these scenarios in the book.

image

There was a little bit of a “down payment” in the first stage for Adatum, but hopefully even in the first chapter you could see the value of approach. For example: how easy it was to enable extranet access and how easy it was to move an app to Windows Azure.

We’ll look now at a new scenario (probably chapter 2 of the Guide) and take further advantage of Adatum’s investments.

The themes for the second “enterprise” scenario are:

  1. Federation with Partners
  2. Home realm discovery

There’s 1 variations in this scenario:

  1. Federating with a Partner with no Identity infrastructure (No IP)

 

The introduction

The situation here is pretty straight forward. As explained before, Adatum uses the a-Orders system to enter and process purchase orders for its Customers. (see scenario #1)

Adatum has received many requests in the past from its customers to have direct access to the order tracking feature in a-Order. They essentially want to be able to track the status of a new purchase order themselves.

a-Order is built on ASP.NET 3.5 and already relies on Adatum’s identity provider as described in the previous article.

Litware is one of such Adatum’s Customers. Rick is an employee @ Litware that frequently submits orders with Adatum. He wants to track orders on a-Order, but he doesn’t want to enter special credentials to do so (yet another username/password). Again, he would like a seamless experience, including SSO.

a-Order is based on roles for access control. In order to query orders’ status, you need to present a claim of type role, with a value “Order Tracker”

 

Key requirements. What do Adatum & Litware want?

Seamless access to a-Order for Litware employees. Access control based on Customer and employee. We want Litware to just browse status of Litware orders, not somebody else’s.

Since a-Order (or more specifically the public pages to check order status) will be public, Adatum needs to know which IP the user is affiliated with (a.k.a. home realm discovery). 

 

What is conceptual solution we propose?

The solution introduces a few new artifacts:

1- Litware Identity Provider (which we assume it already exists and is compatible with Adatum’s. That is WS-Fed)

2- A Federation Provider (FP) in Adatum (which is more of a logical role. It might be physically the same infrastructure the IP is deployed on).

 

The FP in Adatum will maintain a trust relationship with Litware’s IP, and therefore it will trust and understand claims issued by it. In the initial configuration, the claims issued by Litware will just be the name of the employee and the company name (Litware).

In this (simplified) stage we assume a-Order will just filter orders by company (sent as a claim) and by “owner” of the order (also submitted as a claim). Adatum will create a set of new web pages in a-Order that will be published on the internet for Litware.

However, a-Order is built to understand Adatum’s claims, not Litware’s. Moreover, a-Order uses roles to authorize users on different functions, which might not be necessarily issued by Litware (all that Litware issues is the name of the company and the name of the employee submitting the query). Therefore, the FP will also have the responsibility of mapping claims: translating Litware’s into Adatum’s so the application understands them:

 

image

Transformation rules in Adatum’s FP:

There are 3 rules to define in the FP:

Input

Output

Claim Type: Employee Name (Copy input claim)
Claim Issuer: Litware Claim Type: Role      Claim Value: Order Tracker
Claim Type: Company    Claim Value: Company

 

Using ADFS Claim Rule Language:

exists([issuer == "Litware"]) => issue(type = "Role", value = "Order Tracker");

exists([issuer == "Litware"]) => issue(type = "Company", value = "Litware");

c:[type == http://Litware/Employee Name] => issue(claim = c);

 

So, in our example, when Rick@Litware connects to a-Order it will first obtain a claim with his name (“Rick”) from his IP, send them to Adatum’s FP where a new set of claims will be issued:

 

Employee name\Rick –> Employee name\Rick

Issuer: Litware –> Role\Order Tracker

Issuer: Litware –> Company\Litware

 

Notice that this mapping will allow anyone in Litware to track his or her orders, because any valid request will result in the issue of a role claims with “Order Tracker” value.

Caveats:

In a real app you would probably have finer grained access control rules. Like: “only Litware employees working in the Purchasing department can track orders” or something like that. We’ll get there in a more advanced chapter. Be patient! This chapter’s purpose is to introduce a few concepts: claims mapping, FP, home realm discovery, etc.

 

Notice a few things however: new Adatum Customers can easily be added by just setting up the trust relationship in the FP and by creating the right claims mappings. Again, there’s no changes in the app itself. We are also reusing most of the infrastructure we laid out before (like the IP). Thanks to WIF, dealing with claims in a-Order is straight forward and because Adatum is using ADFS v2, creating the claims mapping is also fairly simple.

Also important, notice that the claims Litware issues are about things they are an authority on: the name of one of their employees and their own name. All “identity mismatches” are adjusted on the receiving endpoint (Adatum’s FP). We don’t feel it would be appropriate to request Litware to issue Adatum’s specific claims. Although it is technically possible, we would be contaminating Litware with alien concepts. Think maintenance, troubleshooting issues, etc. 

Last thing in the solution: home realm discovery. a-Order needs to know which IP to direct users to for authentication. If Rick@Litware opens his browser and types http://www.adatum.com/ordertracking how does a-Order know that Rick can be authenticated in Litware’s IP? There are several ways of doing this. Here’s a great (long) article. A simple way would be to ask Rick which company he works for on the web page:

image

Or using the trick of a dedicated url: http://www.adatum.com/ordertracking/litware

 

Variation 1: Adatum working with Customers with NO IP

This is interesting. What could we do if a Litware Customer doesn’t have an IP? Or maybe they have one, but they don’t want to create the trust relationship? Lets say Contoso is such a Customer (Note: Contoso is a truly agile company, isn’t it? :-)).

One solution would be for Adatum  to deploy an IP for customers. This is essentially providing an “convenience IP” for those Customers with no such infrastructure. Interesting question to address is how you would build such IP: could you use ADFS (needs AD behind), or would you build your own (using WIF)?

image

There’s obviously no SSO for poor Jim@Contoso here. But we keep the architecture clean so when Contoso does have one available, migration is trivial.

More importantly perhaps, a-Order treats Contoso in the same way it treats any other Customer. There’re no exceptions. 

Another option for this variation would be to rely on an external IP such as LiveID. But that’s something we have reserved for the ISV track in the Guide, so we would explore that sometime else.

As usual, feedback is greatly welcome.

 

Update:

I changed the original claims mappings proposed for new ones suggested by colleague Peter M. Thompson. In his words:

“I was thinking that the mapping rule should determine Company based on the Claim Issuer instead of the Company claim.  This reduces the risk of an information disclosure attack: a rogue Litware employee (with proper access) sets the Company claim = “Fabrikam” and now Litware employees can view Fabrikam’s orders.”

Thanks Peter!

Welcome to the Enterprise Line, our next stop will be Station #1: “SSO”. Mind the gap.

Disclaimer: this post and the next ones are early drafts to share with you the direction we are taking. They might (and I hope they will) change quite a bit in the actual Guide! We might end up not covering one of these scenarios in the book. These posts represent my ideas and not those of my employer, my colleagues, friends, enemies, associates, pets. Read this at your own risk, got it? :-).

 

image

The themes for our first “enterprise” scenario are:

  1. Intranet and extranet Web SSO
  2. Using claims for user profile information
  3. RBAC with Claims
  4. Single Sign Off
  5. Single company
  6. No federation

Variations in the scenario:

  1. Hosting on Windows Azure

The introduction

Adatum is a medium company that uses Active Directory to authenticate its employees.

John, is a salesman @ Adatum. He uses a-Order, Adatum’s order processing system to enter, process, track and manage customer orders. John also uses a-Expense, an expense tracking and reimbursement system to enter his business related expenses.

Both are built with ASP.NET 3.5 and deployed in Adatum’s datacenter.

a-Order uses Windows integrated authentication. When John uses a Windows domain joined machine, a-Order recognizes the same credentials he used for login on his PC. He’s never prompted for username and password. a-Order user roles are stored in the company’s Active Directory.

a-Expense on the other hand uses a custom authentication, authorization and user profile information. All these data is stored in custom tables in a SQL Server database. John is normally prompted for username and password whenever he uses this application.

a-Expense AuthZ rules are tied to a user name and it’s deeply integrated into the application business logic at all levels (e.g. inside pages, code, stored procedures, etc). It is also something that belongs to the app itself. That is, the roles and information stored in a-Expense doesn’t exist anywhere else in Adatum.

a-Expense was initially used by a handful of employees and over the years, as Adatum grew, it was used by more and more employees. Maintaining the user database (e.g new hires, retiring users, etc) is a cumbersome process and it is not well integrated into Adatum’s existing processes for managing employee accounts.

Some information about the employees using a-Expense does exist somewhere else and needs to the replicated. For example: the “Cost Center” an employee belongs to, is already stored in the corporate AD. Updating Cost Center information in a-Expense is a difficult, error prone process as it is completely manual (each employee has to update its own Cost Center in his profile). Other user preferences (e.g. the reimbursement method: check, direct deposit, cash, etc) is something private to a-Expense.

John as most sales people in Adatum are mobile, often on the road visiting customers. Adatum wants to offer all sales staff the ability to use both applications from anywhere they are, not just its Corpnet (e.g. working from Home, connecting through WiFi access points, etc).

Adatum has many other departmental applications like a-Expense (e.g. a-Vacation, a-Facilities) that are not part of core corporate IT (e.g they have their own user, role and profile databases). Some of these applications are Windows based and others are not. Small applications like this appear all the time.

These apps might not be critical in isolation, but together they add up.

Adatum IT Dept is considering moving some of these applications to “the cloud” to decrease CAPEX and simplify management.

Adatum has also received requests from partners to access their systems. Especially a-Order. Adatum’s customers want to be able to track their orders on Adatum’s system.

 

image

What does Adatum want?

Adatum wants to avoid keeping a username/password just for a-Expense. They want their employees to use the same credentials they use to log on on their desktops.

Adatum also wants a standards based solution that works with multiple platforms and vendors.

Adatum also wants to eliminate common user profile information that needs to be replicated and maintained between multiple repositories (e.g. the Cost Center) where possible

Adatum wants secure internet access for its employees to their systems.

Adatum has big plans in the future. They want to lay the foundation for more advanced scenarios (like providing access to their Customers to other systems, like a-Order).

They also want an architecture that would allow them to easily move some applications to “the cloud” (Windows Azure in particular), and decrease management and CAPEX costs.

 

What is conceptual solution we propose?

We’ll do some forward looking in this scenario, and we’ll make some decisions considering the things we want to achieve in the future

We’ll solve these in multiple steps.

First we’ll introduce an Identity Provider (IP) in the organization. In general we want applications to trust this IP to authenticate its users. In Adatum, an “employee” is a “corporate asset”. No application should keep a custom employee database. It might not be realistic to move all applications initially to use an IP, but for now we just care about a-Expense and a-Order.

This IP will authenticate users and also return common, company wide user information such as the name, the e-mail, the employee cost center, the office number, his phone, etc.

This information is already in AD. We are not requiring (or even suggesting) to change the schema of AD for the needs of any specific application. We are just reusing what’s in there already.

Therefore, some applications will still keep other user profile information that will not be moved to the corporate IP. We want to avoid polluting AD with app specific attributes, we want to keep management decentralized, etc.

We’ll modify a-Order to use IClaimsPrincipal as opposed to IPrincipal and simply return the AD groups as claims. This is in preparation for opening a-Order to external Partners of Adatum later.

a-Expense will continue to use its own application specific roles database associated with the users, but will discontinue to use the user database as authentication is moved to the IP.

Aha! I got you!

At this point, the smart reader could say: what a minute! why all this? Shouldn’t I just enable Windows Authentication in a-Expense? That will give me SSO and it is much much simpler than deploying an IP, issuing claims, configuring the application, etc.

The answer is yes! If that’s all you need, by all means do that. But consider these: 

- This is our first step in a longer journey. We are simplifying things and slightly (we hope) over-complicating others in preparation for other requirements. An investment so to say. (e.g. Customers using a-Order later on) 

- Even now, we want more than just SSO. We want also the ability to move a-Expense to Windows Azure for instance. Windows Authentication is not an option there.

 

In this first stage then we propose:

 

 

image

Adatum wanted to enable John to work from home. One option is to simply publish the apps and the IP on the internet (probably with some firewall rules + proxy). Because there’s no Kerberos authentication happening, the IP will prompt John for Username & Password (the same he uses to login into Adatum network), then it will issue the same token with John claims, and finally he will be redirected to the app:

image

Adatum could choose to add other authentication factors when connecting from the internet (smart card, pin, etc). But whatever they do, the applications don’t care! They are still receiving the same set of claims. Here you see one advantage of factoring out authentication from the application.

The last stage is moving a-Expense to Windows Azure. Can we do that? Sure!

image

Isn’t this beautiful?

Feedback is very much welcome of course.

 

Update: fixed images size.

Claims based Authentication & Authorization Guide – The design of the book

As I mentioned in my previous post, we are going to use a “case study” approach in this book in which we will be presenting a series of concrete scenarios, each one will introduce some very specific requirements. Then we will be showing and discussing possible solutions in that context.

The intent is that each chapter would be more or less self contained, but with references to other sections of the book as needed. The content model for each chapter is roughly this:

 

image

So in the solution space, we will go all the way from design to a complete running example.

There’s some implicit roadmap hinted in the “tube map” for all scenarios. Our intention is to create “learning paths”, so you can choose what to read and in which sequence based on your specific needs. Like taking one train and then a connection somewhere else. Kind of Cortazar’s “Hopscotch”, but without the magic realism. :-)

Before all chapters, there will be an introduction for those who are new to the subject. That’s one of Keith’s key contributions to this project. This “Zen of Federated Identity” will introduce terminology (e.g. what is a claim?, what is a relaying party?, what is an identity provider? an STS? a security token?), explain the basic mechanics of a claims based architecture, its benefits, show some key advantages, etc. In essence we hope it will convince you to keep reading :-). Or help you to quickly make a decision whether this is for you or not. We are all kind of busy to read something not very useful, right?

Apart from sharing with you general information for the project, I plan to discuss quite some detail of each chapter here, so…stay tuned!

My next post we’ll take us to station #1: “SSO”, where we’ll set the foundation for everything else.

As usual, we’d love your feedback.

Update: fixed graphic.

Posted by eugeniop | 0 Comments

Announcing new project – patterns & practices - Claims based Authentication & Authorization Guide

For the next couple of months I’ll be working on a new project here at patterns & practices, developing a new guide for claims based authentication and authorization.

I’m personally very happy to be working on this project, for many reasons. I believe frameworks like “Geneva” (previously known as “Zermatt”, now Windows Identity Foundation), products like “Geneva Server” (now ADFS) are great platform additions to enable a new set of scenarios.

I realize that SSO, Federated Identity and Claims are not new. It’s just that we have much better tools and higher abstractions to implement these scenarios much more easily than ever.

I also feel privileged to work with such a great team. I’ll be sitting on giants shoulders: Dominick Baier, Vittorio Bertocci, Keith Brown, David Hill and Matias Woloski. Many others are joining as advisors and reviewers.

As it is customary now in the patterns & practices team, we will be publishing our content often and very early. I’ll post details here soon.

We also want to try a few new things in this project. In this guide we want to be very focused on the practices rather than on the “theory”, the “principles” or “philosophy” of claims based security.

We want to have very concrete scenarios, with a high fidelity of what happens out there in the real world. Almost a “case study” approach in which we weave a story across the book that takes the reader into more ambitious requirements as he proceeds.

With each chapter, we will introduce more complex solutions to address increasingly more ambitious requirements.

The current backlog for the scenarios we want to cover is illustrated below. Each “station” is a core scenario. Some will have small variations (like Azure hosting in the first one).

 

 

image

The two lines (yellow and light blue) refer to the two perspectives we plan to include: that of someone consuming software (the blue), and that of some building software (the yellow).

Stay tuned!

Eugenio

Update: fixed image size.

First experiments with (new) SQL Data Services

Last week I got my new login to the new SQL Data Services. As a reminder for all readers:

SDS accelerates its plans to offer relational capabilities

May 11, 2009 - Based on customer feedback, SDS has accelerated its plans and will be offering true relational capabilities through SQL Server’s existing network protocol, Tabular Data Stream (TDS) and existing query language Transact-SQL (T-SQL). This will provide customers direct access to the familiar relational model, T-SQL programming language and the existing development and management tools, while continuing to deliver on our key value props of fault tolerance, high availability, friction free provisioning and pay as you grow scaling. For more information, see the SDS product site and the MSDN Library.

 

What I’ve done? After some initial “hello world-ish” tests, I wanted to try something more interesting so I decided to port IssueTracker into SDS.

As you know, IssueTracker was originally designed for SDS’ previous ACE model (Authority, Container, Entity), so my first task was to re-write the data access layer to use SQL Server.

One of my goals in this experiment was to test SDS “impedance match” with on-premises SQL Server. Also, I wanted to develop independently of the availability of SDS. Not that SDS is unreliable, but currently it is available only inside Microsoft’s corporate network. I didn’t want to VPN into corpnet for this when working from home.

So I chose to develop exclusively against my local SQL Express instance first and then make a switch to the real SDS.

Fortunately, the app was designed with a couple of layers that isolated the persistence details, so writing the new data tier was a fairly mechanical process.

This diagram roughly captures the architecture:

clip_image001clip_image002

The repository classes implement a common interface the app uses, the Model is just a collection of rather simple C# objects with no knowledge of the database being used. The Mappers are responsible for the transformations between the application model and the entities that do have knowledge of the database.

In the diagram, classes marked with * are new, the numbers indicate variability points in the implementation, meaning that I can switch between one implementation and the other. Because I used LINQ to SQL, the types in the box labeled as “SQL Model” were generated
automatically by the LINQ to SQL designer.

When my unit tests compiled again, I switched the connection string to point from the “.\SQLEXPRESS” to the SDS instance in our network and…it worked! First attempt! 

image

 

Overall, it was a rather painless and pleasant experience. Of course the data model in the app is simple and I’m not using any advanced queries or any sophisticated features in SQL yet.

 

Things missing and Possible next steps:

The original implementation had 2 requirements that leveraged features in SDS previous ACE model:

1- Multi-tenant isolation: achieved through containers. Each tenant got its own container.

2- Schema flexibility: tenants could customize the application, extending the schema of some core entities. Flexible entities made this very easy, because they are essentially property bags.

 

For #1, I considered two options:

1- Partitioning by tenant

2- Do not partition at all and have all tenants on the same database (single-instance, multi-tenant)

The first option is fairly straight forward. Each tenant gets its own database that is created at provisioning time. The “tenant id” is part of the calling context in the application, so I dynamically connect to each database as needed. Two advantages of this approach: there’s high isolation between tenants (no data from one can leak into another), and the application code is simpler, because from the data perspective, the application is “single-tenant”.

I haven’t implemented the extensibility feature yet, but I’m planning on reusing some techniques we did some research on in the past, probably through extension tables.

 

There’re other interesting areas for research such as:

1- Strategies for partitioning: in discussions with Ryan, he suggested I should consider more sophisticated ways of partitioning the information: by tenant, by tenant + project, etc. and I agree this would be interesting .

2- Unit of Work: currently I’m simply reusing the original ACE implicit UoW that comes with each interaction. This is, each time you called Create, Delete or Update on SDS, the operation was completed in the context of a unit of work. You could not logically group multiple operation (say, 2 creates and 1 delete). This is suboptimal with the SQL implementation, because the new SDS supports transactions and I would like to leverage that.

3- Performance and scalability issues: I haven’t spent any time looking at the application’s “chattiness” with the database that might lead to degraded performance, or any other data access optimizations. This is a whole area in itself, but not very different from “regular” application development. The only exception perhaps is that, in theory at least, the app and the database can be hosted in different datacenters (say the app in Amazon and the data in SDS). I’m not sure that would be a good idea anyway, probably not for this scenario. If the app was hosted in Windows Azure and used SDS, then they would be close in terms of network distance (low latency & high bandwidth). 

Windows Azure 101 – Primitives and Application Patterns – Playing Mendeleyev

Windows Azure’s primitives are very simple, but as in many other things, the power comes from the combination of these simpler primitives to create more complex things.

Look around and see how many things can be assembled from a little more than 100 “simple” elements.

In Windows Azure,  there are essentially 2 types of building blocks: code hosts blocks and persistent bocks   

image

The code hosts run (your) code, the persistence blocks store data.

There are 2 types of Code Hosts:

  1. Interactive: ASP.NET & WCF
  2. Non-interactive: Worker

The interactive building blocks, whether it is a human initiated interaction (ASP.NET) or a programmatic interaction (WCF), is what is referred in Windows Azure terminology as a “Web Role”.  The web role is specialized in “request – response” types of interactions. A user or a program submits a requests, the request is received, analyzed and processed, then a response is sent back. The goal is to process a lot of these concurrent requests and to keep the time between a request and a response as small as possible.

The non-interactive building block is known in Windows Azure as “Worker Role”, and it is the classic background processor. 

There are 3 persistence building blocks. All of them store information, but have specialized functions:

  1. Table: stores records with properties
  2. Blobs: stores “things” with associated metadata
  3. Queue: stores strings with FIFO semantics for retrieval

That’s it.

 

So let’s explore what you could do with this.

A relatively simple web site, like a simple blog engine would be this:

 

image

The front end web role is the app itself: pages, views, controllers, (whatever you use for the logic of the app). All operations (reads/writes) against the store where posts, comments and images would be stored are synchronous.

Adding one block will give you an RSS feed (e.g. using Syndication APIs in WCF):

 

image

And now you can independently manage (e.g. scale) your web viewers from those using an aggregator.

Now let’s imagine you’d like to create a heat map similar to the one you see in my blog, showing where are your readers are located. One possible way of solving this calling a components in the RSS or Web nodes providing as input the IP address of the requestor. The component would then lookup somewhere the country or region associated with the IP address and add one to the counter of that specific country/region. This computation will take penalize the request/response for something that the reader is not necessarily interested in. Besides the lookup IP/country might depend on an external call to another service, with even further penalties.

A better solution would be to offload these to another (background) process that con compute the information with minimal cost to the original request:

 

image

Now the front end nodes will only pay the cost of writing to a queue. The lookup/conversion/heat map generation is done in the background by the worker. You can imagine dynamically creating new instances of the worker if the queue gets too long. Anything that can be postponed for a while, can be pushed to an asynchronous worker for processing (e.g. reporting, analysis, etc)

These are just 6 elements in Microsoft’s larger table of elements for cloud development (.NET Services, SQL Data Services, etc).

These patterns are of course well known (and old :-)), but are proven. Windows Azure gives us a nice way of implementing them plus a way of managing them once they are deployed.

 

Technorati Tags:

More Posts Next page »
 
Page view tracker