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):
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”?
Let’s see how this would work:
- 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.
- Again, John will be redirected to Adatum’s Issuer, because that is what Fabrikam’s Issuer trusts.
- 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:
- 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.
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.
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.
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.
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!