Claims-based Identity and Access Control Guide RTM!
March 5th, 2010
I found myself posting more on twitter than my blog. However this deserved a post.
The RTM of the guide is finally out there in PDF version.
- Book content online on MSDN.
- Book PDF download
- Final samples download
- Discuss at Codeplex
Looking at my name in the cover of a book together with such a group of experts is really a significant milestone in my career. I want to specially thanks Eugenio for trusting me and inviting me to participate in this project. Hope you find the content useful. If you have any questions or you want to discuss about claims, identity, federation towards your next project feel free to mail me at matias at southworks dot net.
Now heading towards the second book: Cloud Guidance! Stay tuned…
Claims based Authentication & Authorization: The Guide
August 15th, 2009
Eugenio announced yesterday the kickoff of a new guide from patterns & practices in which I’m collaborating: Claims based Authentication & Authorization Guide.
This is not a new topic as Eugenio suggests in his blog, but it’s getting more and more attention because:
- Technology is more mature, hence it’s easier to implement claim-based identity
- Enterprises are failing to control the amount of different identity repositories, leading to higher provisioning/deprovisioning costs, security problems, etc.
- End users want simpler user experiences and less passwords
- The cloud makes all these even more challenging
We started with this project a couple of weeks ago planning the content. The approach we decided to use was heavily driven by scenarios (aka zero bulls**t). We used the visual metaphor of a tube map with scenarios being the stations separated in two main lines:
- The blue one, the Enterprise track approaches the federated identity problem from the point of view of a company with many applications that wants to implement SSO and Federation. The main stations are SSO (within the enterprise), Federation (with partners), SOAP Web Services (and flow of identity across services), SSO with a third party cloud app and some variations like: what if the company decides to host an application on the cloud (namely Windows Azure); or what if the company needs to integrate with an application that talks SAML protocol (i.e. Salesforce, Google Apps)
- The yellow one, ISV track on the other hand tackle the problem from the perspective of an ISV that wants to offer an application as a service (think about Salesforce or Dynamics CRM Online as the canonical examples). In this track we start by explaining how to implement federated identity for a cloud application. Then we show how to automate federation to on board new customers. We also show things like exposing a REST API and how that plays with claims; how to integrate with LiveID (or OpenID) for small customers that don’t have an Identity Provider in place; and we end up explaining how to do auditing/billing with claims.
I’m very proud and excited about being part of such a great team including: Dominick Baier, Vittorio Bertocci, Keith Brown, David Hill and Eugenio Pace. I’m sure that something great will come up from this team, the board of reviewers and the community that will help to prioritize and keep the focus!
Getting a token from ADFS (ex Geneva Server) using WCF
July 17th, 2009
I’ve been doing some tests to get a token from ADFS (Geneva Server) using Windows Identity Foundation WSTrustClient. In this case we are using the UserNameMixed endpoint that expects a WS-Security UsernameToken (notice the MessageCredentialType.UserName).
internal static ClaimsIdentityCollection RequestTokenWithUsernameMixed()
{
var binding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential, false);
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.EstablishSecurityContext = false;
var credentials = new ClientCredentials();
credentials.UserName.UserName = "Mary";
credentials.UserName.Password = "Passw0rd!";
var endpoint = "https://mygenevaserver/Trust/13/UsernameMixed";
var client = new WSTrustClient(binding, new EndpointAddress(new Uri(endpoint)), TrustVersion.WSTrust13, credentials);
var request = new RequestSecurityToken();
request.RequestType = "http://schemas.microsoft.com/idfx/requesttype/issue";
request.AppliesTo = new EndpointAddress("http://localhost/activerp");
var token = client.Issue(request) as GenericXmlSecurityToken;
var claims = token.ToClaimsIdentityCollection(TrustVersion.WSTrust13, CertificateUtility.GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=Geneva Signing Certificate - WIN-66EYOLL2BVY"), CertificateUtility.GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=WMSvc-WIN-66EYOLL2BVY"));
return claims;
}
Here is another one using the WindowsMixed endpoint (notice the MessageCredentialType.Windows and no username and password set)
internal static ClaimsIdentityCollection RequestTokenWithWindowsMixed()
{
var binding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential, false);
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
binding.Security.Message.EstablishSecurityContext = false;
var credentials = new ClientCredentials();
var endpoint = "https://mygenevaser/Trust/13/WindowsMixed";
var client = new WSTrustClient(binding, new EndpointAddress(new Uri(endpoint)), TrustVersion.WSTrust13, credentials);
var request = new RequestSecurityToken();
request.RequestType = "http://schemas.microsoft.com/idfx/requesttype/issue";
request.AppliesTo = new EndpointAddress("http://localhost/activerp");
var token = client.Issue(request) as GenericXmlSecurityToken;
var claims = token.ToClaimsIdentityCollection(TrustVersion.WSTrust13, CertificateUtility.GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=Geneva Signing Certificate - WIN-66EYOLL2BVY"), CertificateUtility.GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=WMSvc-WIN-66EYOLL2BVY"));
return claims;
}
You can use this together with the CreateChannelWithIssuedToken extension method (as shown in a previous post).
Identity thoughts #2: Level 2 Authorization
June 17th, 2009
In my last post I talked about an identity roadmap and how we are helping companies to achieve Level 1: Externalizing Authentication. In this first level, we only care about checking the credentials of a user in a Security Token Service and issue a token with a couple of claims. That token will be enough to prove access to the application.
Reaching the Level 1 will make a great difference to the IT department of a given company. By having a central login place they will be able to answer to questions like “when someone logged in to a certain application?”, “which applications someone used in this timeframe?”, etc. In terms of governance, having a single way to implement login will allow the architecture department (if any) to decrease security threats because there is a single well thought piece of infrastructure to perform user authentication across all apps. As a side effect it will also reduce costs of development and maintenance.
Level 2 talks about the authorization process. The authorization decision happens near the application or the service because it knows about the resource (each application has a different domain model).
Geneva Server – Level 1 Authentication
- SSO & Federation – unified login experience and federation with partners
- Centralized Claim Mapping management
- Externalize authentication
- Near the identity provider
- Questions it will answer
- When a subject logged in to an app?
- What claims the subject presented to the app?
Policy Server - Level 2 Authorization
- Policy Enforcement
- Centralized Policy Rules management
- Externalize authorization
- Near the application
- Questions it will answer
- What permissions did the subject requested?
- What permissions where denied?
The following figure shows a very high level architecture of the components and its interactions
Resources
[XACML] http://www.oasis-open.org/committees/xacml/
[Geneva Server] http://connect.microsoft.com/content/content.aspx?ContentID=10106&SiteID=642
[SAML] http://www.oasis-open.org/specs/#samlv2.0
The following table shows an analogy of identity concepts between a single application and a federated application.
The single app has its own identity silo and the federated app relies on an STS (like Geneva Server). I find this analogy useful to explain how things differ from the non-federated non-claim-based world.
Scenario: Token Exchange when you can’t change the client
May 23rd, 2009
Couple of months ago Ezequiel posted a summary of a very interesting article published on the Identity issue of the Architecture Journal. This article talked about different patterns on the federated identity world. Last week we had an interesting requirement to solve in a project and this article came to my mind. Specifically one of the scenarios this article points out is when you don’t want the consumer to have knowledge about the relying party STS or you don’t want the client to “see” the token from that STS. The figure below illustrates this scenario. In this diagram, the relying party (service) will receive a token from STS A and will call the STS B to obtain the token.
This might be helpful when you can’t change the consumer side of the equation. This lead me to introduce the federated blog engine and how we leveraged this in that project…
The Federated Blog Engine
Let’s say we want to implement a blog engine where users can access through federated identity. My blog engine supports the passive profile federation, so when someone access it will get redirected to its IP STS, get authenticated, post the token to the website and voila! We can create new blog posts under our organization identity.
So far nothing new here. Now let’s say that we want to be able to post through Windows Live Writer. This is a rich client that runs on your desktop that you can’t change. On the other side the blog engine will have to expose the MetaWeblog API. Every operation of this API receives the user and password like the code below:
string NewPost(string blogId, string username, string password, Post post, bool publish);
In this case, the token on the client is a UsernameToken (not the WS-Security one, but think about the analogy). We will send that token (through Https) to the remote MetaWeblog API.
NewPost("mwoloski", "DOMAIN\matias", "mypassword", post, true)
When the message gets to the service we can intercept it and call the STS that will validate the credentials and will issue a SAML token for the service. The following piece of code shows how to make such request to a Geneva Server Beta 2 using the UserNameMixed endpoint. This endpoint will authenticate the user against AD.
private static ClaimsIdentityCollection GetToken(string username, string password, Uri stsUrl, X509Certificate2 signatureCertificate, Uri relyingPartyIdentifier, X509Certificate2 decryptingCertificate){ var binding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential, false); binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; binding.Security.Message.EstablishSecurityContext = false; var credentials = new ClientCredentials(); credentials.UserName.UserName = username; credentials.UserName.Password = password; var client = new WSTrustClient(binding, new EndpointAddress(stsUrl), TrustVersion.WSTrust13, credentials); var request = new RequestSecurityToken(); request.RequestType = "http://schemas.microsoft.com/idfx/requesttype/issue"; request.AppliesTo = new EndpointAddress(relyingPartyIdentifier); var token = client.Issue(request) as GenericXmlSecurityToken; var claims = token.ToClaimsIdentityCollection(TrustVersion.WSTrust13, signatureCertificate, decryptingCertificate); return claims;}
var token = GetToken("matias", "password", new Uri("https://genevaserverurl/Trust/13/UsernameMixed"), CertificateUtility.GetCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, "CN=Geneva Signing Certificate…"), new Uri("http://hostname/someservice"), CertificateUtility.GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=hostname"))

