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.
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:
- Federation with Partners
- Home realm discovery
There’s 1 variations in this scenario:
- Federating with a Partner with no Identity infrastructure (No IP)
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:
Transformation rules in Adatum’s FP:
There are 3 rules to define in the FP:
|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.
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:
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)?
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.
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.”