MSDN Magazine - October 2008 - (Page 68) Claims-Based Authorization Once you reach a critical mass of services and complexity, rolebased security may not be powerful or flexible enough. It doesn’t take much for an enterprise scale, service-oriented application to become extremely complicated. Various clients using various client frameworks and credential types talk to various back-end services. These back-end services, in turn, call other services. Sometimes this is done in a trusted subsystem fashion where only the direct caller is authorized. Alternately, sometimes the original caller identity has to be forwarded throughout the call chain. The situation starts to get really complex as soon as external clients (such as partners or customers) need access to some of your internal services. as Zermatt are not bound in any way to WCF and can be used to claims enable any .NET application. It just happens that these APIs are deeply integrated into WCF. The most important structural classes from the System.IdentityModel namespace that you need to understand are called Claim, ClaimSet, AuthorizationContext, and AuthorizationPolicy. We will now have a closer look at each of them and explore how they are integrated into the WCF security system. Claim It is useful to have centralized logic that can inspect every incoming request. It quickly becomes apparent that, in a more complex system, the capabilities of IIdentity and IPrincipal may not be sufficient to model identity and authorization data. Role-based security is limited to binary decisions and does not allow arbitrary data to be associated with a subject. A technology-neutral format is needed that allows describing the identities of entities participating in your distributed system. This is why the .NET Framework, starting in version 3.0, contains a new identity and access-control API that can handle these requirements with a claims-based approach. You can find this new API in the System.IdentityModel assembly and namespace. Furthermore, Microsoft just recently released a preview of its new identity framework code-named “Zermatt.” This new framework builds upon the classes and concepts found in System.IdentityModel and makes it easier to build claims-based security into services and applications. It is important to note that System.IdentityModel as well Figure 4 A Service Authorization Manager Code class AuthorizationManager : ServiceAuthorizationManager { public override bool CheckAccess( OperationContext operationContext, ref Message message) { base.CheckAccess(operationContext, ref message); string action = operationContext.IncomingMessageHeaders.Action; if (action == 'urn:msdnmag/IService/GetRoles') { // messags in WCF are always read-once // we create one copy to work with, and one copy for WCF MessageBuffer buffer = operationContext.RequestContext.RequestMessage. CreateBufferedCopy(int.MaxValue); message = buffer.CreateMessage(); // get the username value using XPath XPathNavigator nav = buffer.CreateNavigator(); StandardNamespaceManager nsm = new StandardNamespaceManager(nav.NameTable); nsm.AddNamespace('msdn', 'urn:msdnmag'); XPathNavigator node = nav.SelectSingleNode A claim is a piece of information that can be associated with an entity in your system. This is most commonly a user but could also be a service or some resource. A claim consists of three pieces of information: a claim type, the claim content, and whether the claim describes the identity of the subject or a capability of the subject. This data structure is represented by a class known as System.IdentityModel.Claims.Claim. Furthermore, Claim is a DataContract, which makes it serialization-friendly (important when you plan to transmit claims over service boundaries): [DataContract(Namespace = 'http://schemas.xmlsoap.org/ws/2005/05/identity')] public class Claim { [DataMember(Name = 'ClaimType')] public string ClaimType; [DataMember(Name = 'Resource')] public object Resource; [DataMember(Name = 'Right')] public string Right; } ClaimType is a URI that identifies the claim type. While you can come up with your own type URI, several standard claim types are available from the ClaimTypes class. A claim representing a name could use the URI value held by ClaimTypes.Name: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name The Resource property contains the actual claim value. Note that the Resource is of type object—this means that you could associate arbitrarily complex information with that claim (from a simple string to a complete graph). Just keep in mind that this may become ('s:Envelope/s:Body/msdn:GetRoles/msdn:username', nsm); string parameter = node.InnerXml; // check authorization if (operationContext.ServiceSecurityContext.PrimaryIdentity.Name == parameter) { return true; } else { return (GetPrincipal(operationContext).IsInRole( 'administrators')); } } } return true; } // rest omitted Configuration 68 msdn magazine Service Station
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.