Microsoft Enterprise Library: Authorization and Security Cache

Develop Enterprise applications using reusable software components of Microsoft Enterprise Library 5.0 with this book and eBook

 

Microsoft Enterprise Library 5.0

Microsoft Enterprise Library 5.0

Develop Enterprise applications using reusable software components of Microsoft Enterprise Library 5.0

  • Develop Enterprise Applications using the Enterprise Library Application Blocks
  • Set up the initial infrastructure configuration of the Application Blocks using the configuration editor
  • A step-by-step tutorial to gradually configure each Application Block and implement its functions to develop the required Enterprise Application

 

        Read more about this book      

(For more resources on Microsoft Enterprise Library, see here.)

Understanding Authorization Providers

An Authorization Provider is simply a class that provides authorization logic; technically it implements either an IAuthorizationProvider interface or an abstract class named AuthorizationProvider and provides authorization logic in the Authorize method. As mentioned previously, the Security Application Block provides two Authorization Providers out of the box, AuthorizationRuleProvider and AzManAuthorizationProvider both implementing the abstract class AuthorizationProvider available in the Microsoft.Practices.EnterpriseLibrary.Security namespace. This abstract class in turn implements the IAuthorizationProvider interface, which defines the basic functionality of an Authorization Provider; it exposes a single method named Authorize, which accepts an instance of the IPrincipal object and the name of the rule to evaluate. Custom providers can be implemented either by implementing the IAuthorizationProvider interface or an abstract class named AuthorizationProvider.

An IPrincipal instance (GenericPrincipal, WindowsPrincipal, PassportPrincipal, and so on) represents the security context of the user on whose behalf the code is running; it also includes the user's identity represented as an instance of IIdentity (GenericIdentity, FormsIdentity, WindowsIdentity, PassportIdentity, and so on).

The following diagram shows the members and inheritance hierarchy of the respective class and interface:

Microsoft Enterprise Library

Authorization Rule Provider

The AuthorizationRuleProvider class is an implementation that evaluates Boolean expressions to determine whether the objects are authorized; these expressions or rules are stored in the configuration file. We can create authorization rules using the Rule Expression Editor part of the Enterprise Library configuration tool and validate them using the Authorize method of the Authorization Provider. This authorization provider is part of the Microsoft.Practices.EnterpriseLibrary.Security namespace.

Authorizing using Authorization Rule Provider

Authorization Rule Provider stores authorization rules in the configuration and this is one of the simplest ways to perform authorization. Basically, we need to configure to use the Authorization Rule Provider and provide authorization rules based on which the authorization will be performed.

Let us add Authorization Rule Provider as our Authorization Provider; click on the plus symbol on the right side of the Authorization Providers and navigate to the Add Authorization Rule Provider menu item.

The following screenshot shows the configuration options of the Add Authorization Rule Provider menu item:

Microsoft Enterprise Library

The following screenshot shows the default configuration of the newly added Authorization Provider; in this case, it is Authorization Rule Provider:

Microsoft Enterprise Library

Now we have the Authorization Rule Provider added to the configuration but we still need to add the authorization rules. Imagine that we have a business scenario where:

  • We have to allow only users belonging to the administrator's role to add or delete products.
  • We should allow all authenticated customers to view the products.

This scenario is quite common where certain operations can be performed only by specific roles, basically role-based authorization. To fulfill this requirement, we will have to add three different rules for add, delete, and view operations. Right-click on the Authorization Rule Provider and click on the Add Authorization Rule menu item as shown on the following screenshot.

Microsoft Enterprise Library

The following screenshot shows the newly added Authorization Rule:

Microsoft Enterprise Library

Let us update the name of the rule to "Product.Add" to represent the operation for which the rule is configured. We will provide the rule using the Rule Expression Editor; click on the right corner button to open the Rule Expression Editor. The requirement is to allow only the administrator role to perform this action. The following action needs to be performed to configure the rule:

  1. Click on the Role button to add the Role expression: R.
  2. Enter the role name next to the role expression: R:Admin.
  3. Select the checkbox Is Authenticated to allow only authenticated users.

The following screenshot displays the Rule Expression Editor dialog box with the expression configured to R:Admin.

Microsoft Enterprise Library

The following screenshot shows the Rule Expression property set to R:Admin.

Microsoft Enterprise Library

Now let us add the rule for the product delete operation. This rule is configured in a similar fashion. The resulting configuration will be similar to the configuration shown.

The following screenshot displays the added authorization rule named Product.Delete with the configured Rule Expression:

Microsoft Enterprise Library

Alright, we now have to allow all authenticated customers to view the products. Basically we want the authorization to pass if the user is either of role Customer; also Admin role should have permission, only then the user will be able to view products. We will add another rule called Product.View and configure the rule expression using the Rule Expression Editor as given next. While configuring the rule, use the OR operator to specify that either Admin or Customer can perform this operation.

The following screenshot displays the added authorization rule named Product.View with the configured Rule Expression:

Microsoft Enterprise Library

Now that we have the configuration ready, let us get our hands dirty with some code. Before authorizing we need to authenticate the user; based on the authentication requirement we could be using either out-of-the-box authentication mechanism or we might use custom authentication. Assuming that we are using the current Windows identity, the following steps will allow us to authorize specific operations by passing the Windows principal while invoking the Authorize method of the Authorization Provider.

  1. The first step is to get the IIdentity and IPrincipal based on the authentication mechanism. We are using current Windows identity for this sample.
    WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
    WindowsPrincipal windowsPrincipal = new WindowsPrincipal(windowsId
    entity);
  2. Create an instance of the configured Authorization Provider using the AuthorizationFactory.GetAuthorizationProvider method; in our case we will get an instance of Authorization Rule Provider.
    IAuthorizationProvider authzProvider = AuthorizationFactory.GetAut
    horizationProvider("Authorization Rule Provider");
  3. Now use the instance of Authorization Provider to authorize the operation by passing the IPrincipal instance and the rule name.
    bool result = authzProvider.Authorize(windowsPrincipal, "Product.
    Add");

AuthorizationFactory.GetAuthorizationProvider also has an overloaded alternative without any parameter, which gets the default authorization provider configured in the configuration.

AzMan Authorization Provider

The AzManAuthorizationProvider class provides us the ability to define individual operations of an application, which then can be grouped together to form a task. Each individual operation or task can then be assigned roles to perform those operations or tasks. The best part of Authorization Manager is that it provides an administration tool as a Microsoft Management Console (MMC) snap-in to manage users, roles, operations, and tasks. Policy administrators can configure an Authorization Manager Policy store in an Active Directory, Active Directory Application Mode (ADAM) store, or in an XML file. This authorization provider is part of the Microsoft.Practices.EnterpriseLibrary.Security namespace.

        Read more about this book      

(For more resources on Microsoft Enterprise Library, see here.)

Understanding Security Cache Provider

Security Cache Provider allows us to cache, retrieve instances of IIdentity, IPrincipal, or Profile objects (such as the ASP.NET Profile object), and additionally purge/expire the same. It also generates a token of type IToken and this token can be used to purge/expire the cache. The SecurityCacheProvider class is an abstract implementation of the ISecurityCacheProvider interface; both are part of the Microsoft.Practices.EnterpriseLibrary.Security namespace. The ISecurityCacheProvider interface consists of methods such as SaveIdentity, SavePrincipal, and SaveProfile; all three methods have their overloaded counterparts to accept an instance of IToken to group each of these objects with the same token. It also provides methods such as GetIdentity, GetPrincipal, and GetProfile to retrieve cached credentials; these methods accept instance of IToken. Apart from saving and retrieving, ISecurityCacheProvider also exposes methods to expire cached items; ExpireIdentity, ExpirePrincipal, and ExpireProfile. These methods accept an instance of IToken to expire the respective cached item.

The following diagram shows the members and inheritance relationship of the respective classes related to Security Cache Provider.

Microsoft Enterprise Library

CachingStoreProvider class

The CachingStoreProvider class is a concrete implementation of the SecurityCacheProvider class; it leverages the Caching Application Block for its caching needs. This class provides the logic to obtain a token for an authenticated user and manage caching for authenticated IIdentity, IPrincipal, or Profile objects (such as the ASP.NET Profile object). The CachingStoreProvider class is part of the Microsoft.Practices.EnterpriseLibrary.Security.Cache.CachingStore namespace.

Configuring Security Cache Provider

To leverage security caching related functionality, let us add the built-in CachingStoreProvider Security Cache Provider in the configuration. This provider uses the caching mechanism implemented by the Caching Application Block. In the configuration file, click on the plus symbol of the Security Caches section and navigate to the Add Security Cache menu item as shown in the following screenshot:

Microsoft Enterprise Library

The following screenshot shows the default configuration of Security Cache:

Microsoft Enterprise Library

We have configured the Security Cache Provider and are ready to use it in our code to perform various actions against the Security Cache Provider.

Caching and generating a token for an authenticated user

Frequent authentication of user during a single session may lead to performance degradation of the application; we can obtain a temporary token by saving a user principal or a user identity in the security cache. We can save user identity, principal and/or profile; one or more objects can be combined using the same token. Caching an IIdentity, IPrincipal, or Profile is just a two-step process; everything else is taken care of by the configuration. As mentioned earlier, Security Cache Provider uses the Caching Application Block for caching, which gives us all the flexibility of configuration to select the storage mechanism, encryption, and expiration policy. Also, the generated IToken can be used to retrieve cached items or mark them for expiration.

The following code snippet gets the current Windows identity and checks whether the identity is authenticated. Upon validation, the instance of Security Cache Provider is used to save the identity and generate the token:

//Get current Windows Identity
WindowsIdentity identity = WindowsIdentity.GetCurrent();

if (identity.IsAuthenticated)
{
ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();

//Cache User Identity and generate token
IToken token = cacheProvider.SaveIdentity(identity);
}

For ASP.NET Web Applications, User Identity can be obtained by accessing the property Page.User.Identity.ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.Current.GetInstance <ISecurityCacheProvider>();
cacheProvider.SaveIdentity(Page.User.Identity);

The following code snippet gets the current Windows identity and for the purposes of the demonstration, creates a GenericPrincipal object with Manager role. The instance of Security Cache Provider is used to save the principal and generate the token:

//Get current Windows Identity
WindowsIdentity identity = WindowsIdentity.GetCurrent();

//Constructing dummy Principal Object for demonstration
GenericPrincipal principal = new GenericPrincipal(identity, new
string[] { "Manager" });

if (identity.IsAuthenticated)
{
ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();

//Cache IPrincipal and generate token
IToken token = cacheProvider.SavePrincipal(principal);
}

For ASP.NET Web Applications, the respective IPrincipal instance can be obtained by accessing the property Page.User.

The following code snippet demonstrates the Profile caching feature; the SaveProfile method of Security Cache Provider is used to save the profile object and generate the token:

ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();
IToken token = cacheProvider.SaveProfile(HttpContext.Current.Profile);

Associating a token with User Identity, Principal and Profile objects

We can associate an existing token while caching instead of generating a new token, which allows grouping of Identity, Principal, and Profile objects. To utilize this grouping functionality, we have to use the respective overloaded save method and pass the instance of the token as the second parameter.

The following code snippet demonstrates how to associate the generated token while saving Identity, Principal, and Profile objects:

//Constructing dummy Principal Object for demonstration
GenericPrincipal principal = new GenericPrincipal(Page.User.Identity,
new string[] { "Manager" });

if (Page.User.Identity.IsAuthenticated)
{
ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();

//Cache IIdentity and generate token
IToken token = cacheProvider.SaveIdentity(Page.User.Identity);

//Cache IPrincipal and group token with related items
cacheProvider.SavePrincipal(principal, token);

//Cache Profile object and group token with related items
cacheProvider.SaveProfile(HttpContext.Current.Profile, token);
}

Retrieving User Identity, User Principal, and Profile objects

The following code block first creates an instance of the Security Cache Provider and then saves the respective items, which generates an IToken instance, which can be used to retrieve the respective item. Currently IToken is an instance of GuidToken, which generates a Guid; this can be stored for the user's session in the appropriate location based on the application type. The token can be re-generated using the Guid and authentication information can be validated as well as authorization being performed by retrieving the IPrincipal instance from the security cache.

The following code snippet demonstrates how to retrieve the Identity object using the generated token:

//Get current Windows Identity
IIdentity identity = WindowsIdentity.GetCurrent();

ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();

//Cache Identity and generate token
IToken token = cacheProvider.SaveIdentity(identity);

//Retrieve Identity using token
IIdentity cachedIdentity = cacheProvider.GetIdentity(token);

The following code snippet demonstrates how to retrieve the Principal object using the generated token:

//Constructing dummy Principal Object for demonstration
GenericPrincipal principal = new GenericPrincipal(Page.User.Identity,
new string[] { "Manager" });

if (Page.User.Identity.IsAuthenticated)
{
ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();

//Cache IIdentity and generate token
IToken token = cacheProvider.SaveIdentity(Page.User.Identity);

//Cache IPrincipal and group token with related items
cacheProvider.SavePrincipal(principal, token);

//Retrieve cached Principal using token
cacheProvider.GetPrincipal(token);
}

The following code snippet demonstrates how to retrieve the Profile object using the generated token:

ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();

//Cache Profile object and generate token
IToken token = cacheProvider.SaveProfile(HttpContext.Current.Profile);

//Retrieve cached Profile using token
ProfileBase profile = cacheProvider.GetProfile(token) as ProfileBase;

Expiring User Identity, User Principal, and Profile objects

Security Cache Provider also provides the ability to expire the cached item when the user logs out of the system or the session ends so that the token cannot be misused. This functionality is part of the ExpireIdentity, ExpirePrincipal, and ExpireProfile methods of Security Cache Provider. In the given code blocks, we are creating an instance of the Security Cache Provider and then saving the respective items, which generates an IToken instance. The same token is used to force expiration of the cached item. Please note we are deliberately performing the cache and immediately forcing expiration in the next line just to give you the full picture.

The following code snippet demonstrates how to purge/expire the saved Identity using the generated token:

ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();

//Cache IIdentity and generate token
IToken token = cacheProvider.SaveIdentity(Page.User.Identity);

//Purge/Expire an existing cached Identity using token
cacheProvider.ExpireIdentity(token);

The following code snippet demonstrates how to purge/expire the saved Principal using the generated token:

//Constructing dummy Principal Object for demonstration
GenericPrincipal principal = new GenericPrincipal(Page.User.Identity,
new string[] { "Manager" });

if (Page.User.Identity.IsAuthenticated)
{
ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();

//Cache IIdentity and generate token
IToken token = cacheProvider.SaveIdentity(Page.User.Identity);

//Cache IPrincipal and group token with related items
cacheProvider.SavePrincipal(principal, token);

//Purge/Expire the existing cached Principal using token
cacheProvider.ExpirePrincipal(token);
}

The following code snippet demonstrates how to purge/expire the saved Profile object using the generated token:

ISecurityCacheProvider cacheProvider = EnterpriseLibraryContainer.
Current.GetInstance<ISecurityCacheProvider>();

//Cache Profile object and generate token
IToken token = cacheProvider.SaveProfile(HttpContext.Current.Profile);

//Purge/Expire the cached Profile using token
cacheProvider.ExpireProfile(token);

Implementing a custom Authorization Provider

The Security Application Block provides extension points to implement a custom authorization provider; we may extend either the IAuthorizationProvider interface or the abstract class AuthorizationProvider. The Authorize method is where we need to provide our authorization logic. Both the extension points are part of the Microsoft.Practices.EnterpriseLibrary.Security namespace.

Following is the IAuthorizationProvider interface which exposes the Authorize method:

public interface IAuthorizationProvider
{
bool Authorize(IPrincipal principal, string context);
}

The following code snippet shows the implementation of the AuthorizationProvider abstract class, which inherits the IAuthorizationProvider interface and provides wiring of the instrumentation provider for instrumentation purposes:

public abstract class AuthorizationProvider : IAuthorizationProvider
{
IAuthorizationProviderInstrumentationProvider
instrumentationProvider;

protected AuthorizationProvider()
: this(new NullAuthorizationProviderInstrumentationProvider())
{
}
protected
AuthorizationProvider(IAuthorizationProviderInstrumentationProvider
instrumentationProvider)
{
if (instrumentationProvider == null) throw new ArgumentNullExc
eption("instrumentationProvider");
this.instrumentationProvider = instrumentationProvider;
}
public abstract bool Authorize(IPrincipal principal, string
context);
protected IAuthorizationProviderInstrumentationProvider
InstrumentationProvider
{
get { return this.instrumentationProvider; }
}
}

Custom XML Authorization Provider

Implementing a custom authorization provider is pretty straight-forward. We can inherit from the AuthorizationProvider class and provide an override the Authorize method to provide our authorization logic. Apart from that, we also have to decorate the class with the ConfigurationElementType attribute. To make our job easy, the application block provides the CustomAuthorizationProviderData class, which holds a configuration object for custom providers. This class is part of the Microsoft.Practices.EnterpriseLibrary.Security.Configuration namespace.

The following code snippet shows a typical custom Authorization Provider implementation:

[ConfigurationElementType(typeof(CustomAuthorizationProviderData))]
public class XmlAuthorizationProvider : AuthorizationProvider
{
public XmlAuthorizationProvider(NameValueCollection
configurationItems) { }

public override bool Authorize(IPrincipal principal, string
context)
{
// Custom authorization logic goes here
// Return true or false based on the authorization outcome
return false;
}
}

Summary

In this article we have explored the elements of Authorization and Security Cache Providers. We have learned about the various required and optional assemblies. We saw how to configure the initial configuration and also the Authorization Rule Provider, Authorization Rules, as well as Security Cache Provider. We have also learned to authorize based on the configured rules and perform various operations such as saving, retrieving, and expiring instances of IIdentity, IPrincipal, and Profile objects using the Security Cache Provider. Finally, we observed how to implement a custom authorization provider.


Further resources on this subject:


Books to Consider

comments powered by Disqus
X

An Introduction to 3D Printing

Explore the future of manufacturing and design  - read our guide to 3d printing for free