Authorization in Claims-Aware Web Applications and Services
Updated: June 19, 2015
Applies To: Azure
Microsoft Azure Active Directory Access Control (also known as Access Control Service or ACS)
Windows® Identity Foundation (WIF)
Windows Communication Foundation (WCF)
In a relying party application, authorization determines what resources an authenticated identity is allowed to access and what operations it is allowed to perform on those resources. Improper or weak authorization leads to information disclosure and data tampering. This topic outlines the available approaches to implementing authorization for claims-aware ASP.NET web applications and services using ACS and WIF.
List the authorization approaches that use claims.
Outline the high-level design for each approach.
Call out the advantages and disadvantages of each approach.
Since its first version, the .NET Framework has offered a flexible mechanism for implementing authorization. This mechanism is based on two simple interfaces—IPrincipal and IIentity. Concrete implementations of IIentity represent an authenticated user. For example, the WindowsIdentity implementation represents a user who is authenticated by Active Directory, and GenericIdentity represents a user who is authenticated by a custom authentication. Concrete implementations of IPrincipal help to check permissions using roles depending on the role store. For example, WindowsPrincipal checks WindowsIdentity for membership in Active Directory groups. This check is performed by calling the IsInRole method on the IPrincipal interface. Checking access based on roles is called Role-Based Access Control (RBAC). RBAC is explained in the “Role-Based Access Control” section of this topic. Claims can be used to carry information about roles to support familiar, role-based authorization mechanisms.
Claims can also be used to enable much richer authorization decisions beyond roles. Claims can be based on virtually anything—age, zip code, shoe size, and so forth. Checking access based on arbitrary claims is called Claims-Based Access Control (CBAC) or claims-based authorization. Claims-based authorization is explained in the “Claims-Based Access Control” section of this topic.
Authorization checks are performed on the application side, not on the ACS side. ACS serves as a security token service (STS) that issues tokens that carry the claims to the application. The tokens are enriched with claims by identity providers and optionally by ACS itself, using its rules engine. When the application receives the token with claims, it can parse the token, extract the relevant claims, and make authorization decisions using either RBAC or a claims-based approach. WIF is used to parse the token and make it usable for authorization decisions through an easy-to-use application programming interface (API). For more information about WIF, see the WIF SDK (https://go.microsoft.com/fwlink/?LinkID=187481). Consider the following diagram when thinking about authorization in claims-aware applications and services. Note that upon successful authentication the identity provider generates a token (the IdP token on the diagram). The IdP token can be transformed by the ACS rules engine. ACS can add, remove, or change the claims that come in the token that the identity provider issues. Finally, the token issued by ACS is sent to the application and processed by WIF. The access check is accomplished in WIF, using either the RBAC or CBAC approach.
Role-Based Access Control
RBAC is an authorization approach in which user permissions are managed and enforced by an application based on user roles. If a user has a role that is required to perform an action, the access is granted; otherwise, access is denied.
To implement the RBAC approach in claims-aware applications, use the IPrinicpal interface IsInRole() method, just as you would in non-claims-aware applications. There are several ways of using the IsInRole() method:
Explicitly calling on IPrincipal.IsInRole(“Administrator”). In this approach, the outcome is a Boolean. Use it in your conditional statements. It can be used arbitrarily any place in your code.
Using the security demand PrincipalPermission.Demand(). In this approach, the outcome is an exception in case the demand is not satisfied. This should fit your exception handling strategy. Throwing exceptions is much more expensive from a performance perspective compared to retiring Boolean. This can be used any place in your code.
Using the declarative attributes [PrincipalPermission(SecurityAction.Demand, Role = “Administrator”)]. This approach is called declarative, because it is used to decorate methods. It cannot be used in code blocks inside the method’s implementations. The outcome is an exception in case the demand is not satisfied. You should make sure that it fits your exception-handling strategy.
Using URL authorization, using the <authorization> section in web.config. This approach is suitable when you are managing authorization on a URL level. This is the most coarse level among those previously mentioned. The advantage of this approach is that changes are made in the configuration file, which means that the code should not be compiled to take advantage of the change.
Expressing Roles as Claims
When the IsInRole() method is called, there is a check made to see if the current user has that role. In claims-aware applications, the role is expressed by a role claim type that should be available in the token. The role claim type is expressed using the following URI:
There are several ways to enrich a token with a role claim type:
Using the ACS rules engine—In this case you create a rule using the ACS Management Portal or ACS Management Service to create claims transformation rules that generate claims of a certain role type. For more information about rules and token transformation, see Rule Groups and Rules and How to: Implement Token Transformation Logic Using Rules.
Transforming arbitrary claims into of claims role type using ClaimsAuthenticationManager—The ClaimsAuthenticationManager is a component that ships as part of WIF. It allows requests to be intercepted when they launch an application, inspecting tokens and transforming them by adding, changing, or removing claims. For more information about how to use ClaimsAuthenticationManager for transforming claims, see How to: Implement Role Based Access Control (RBAC) in a Claims-Aware ASP.NET Application Using WIF and ACS
Mapping arbitrary claims to a role type using the samlSecurityTokenRequirement configuration section—A declarative approach where the claims transformation is done using only the configuration and no coding is required.
Claims-Based Access Control
CBAC is an authorization approach where the authorization decision to grant or deny access is based on arbitrary logic that uses data available in claims to make the decision. Recall that in the case of RBAC, the only claim used was role type claim. A role type claim was used to check if the user belongs to specific role or not. To illustrate the process of making the authorization decisions using claims-based authorization approach, consider the following steps:
The application receives a request.
The application extracts the incoming claims.
The application passes the claims to the decision logic mechanism. It can be in-memory code or a call to a web service, a query to a database, or it can invoke a sophisticated rules engine.
The decision mechanism calculates the outcome based on the claims.
Access is granted if the outcome is true and denied if it is false. For example, the rule might be that the user is of age 21 or above, lives in Washington State, and was authenticated by Windows Live ID (Microsoft account).
ACS serves as an STS that issues tokens that carry the claims. You can control which claims are being issued—both the types of claims and the values—using the ACS rules engine. To learn more about the ACS rules engine, see Rule Groups and Rules and How to: Implement Token Transformation Logic Using Rules. ClaimsAuthorizationManager is key to implementing CBAC in claims-aware applications. ClaimsAuthorizationManager is a component that ships as part of WIF. ClaimsAuthorizationManager allows you to intercept incoming requests and implement any logic of your choice to make authorization decisions based on the incoming claims. This is also an extensibility point where authorization decisions can be externalized and decoupled from the application code. This becomes important when authorization logic needs to be changed. In that case, using ClaimsAuthorizationManager will not affect the application’s integrity, thereby reducing the likelihood of an application error as a result of the change. To learn more about how to use ClaimsAuthorizationManager to implement claims-based access control, see How to: Implement Claims Authorization in a Claims-Aware ASP.NET Application Using WIF and ACS.