T4 Toolbox: Strongly-typed AzMan wrapper generator


Build 8.12.27.1 of T4 Toolbox includes a new project item template for an AzMan authorization policy XML file and a code generator that produces a C# wrapper for performing operation-based authorization checks against it. The generator creates a separate enumerated type with security operations for each application application in the AzMan policy and a wrapper class with strongly-typed Authorize and CanPerform methods that take these enums as parameters.

As you may have guessed, this code generator is an updated version of the generator I published back in March. The new version takes advantage of the infrastructure provided by T4 Toolbox to generate both enumerated types and the wrapper class in separate files from a single T4 code generator. However, most of the information in the previous article is still valid, including overview of the other methods of working with AzMan authorization policy, such as ASP.NET Role Manager, Security Application Block of the Enterprise Library, Authorization Interoperability Wrapper and why the generated C# wrapper is both easier to use and more powerful than these alternatives.

Usage

  • Download and install the latest version of T4 Toolbox from CodePlex.
  • In Visual Studio, create a new or open an existing C# project and select Project->Add New Item in the main menu.
  • In the Add New Item dialog, select Code Generation->Authorization Store template.

Add New Item dialog, Authorization Store template

  • Enter the name you want to use for the new AzMan XML policy file. Note that this name also determines the name of the C# wrapper class that will be generated for it. Click the Add button when finished.

    image

Note that two files were added to your project - AuthorizationStore.xml and AuthorizationStore.tt (the actual file names will vary depending on the name you entered in the Add New Item dialog).

AuthorizationStore.xml

This file contains an AzMan authorization policy in XML format. Developers use the authorization policy to define one or more applications and a set of operations that can be performed in it. A sample authorization policy shown below defines two applications with two operations each.

<?xml version=1.0encoding=utf-8?>
<!–
  Copyright © Catapult Systems. All Rights Reserved. 

  This file contains XML definition of an AzMan authorization store.
  DO NOT modify this file manually, use Authorization Manager (azman.msc) instead.
–>
<AzAdminManager MajorVersion=1MinorVersion=0Guid=6587ad8f-2e4d-44a7-9f7d-b422d727ee6a>
  <AzApplication Guid=ebde1248-7fc3-4457-bfea-c05476a391c9Name=Application 1Description=This is a sample application 1ApplicationVersion=“”>
    <AzOperation Guid=dc5a319c-f09f-4569-8c44-1bd66d02a597Name=Operation 1Description=This is a sample operation 1 in application 1>
      <OperationID>1</OperationID>
    </AzOperation>
    <AzOperation Guid=d243836d-819d-40aa-9f48-430983378ffaName=Operation 2Description=This is a sample operation 2 in application 1>
      <OperationID>2</OperationID>
    </AzOperation>
  </AzApplication>
  <AzApplication Guid=214e1d5f-8174-4af2-b3f2-a5b7679fd3b7Name=Application 2Description=This is a sample application 2ApplicationVersion=“”>
    <AzOperation Guid=4c7369c8-bb52-4d7e-aa7c-b02b87ef529cName=Operation 1Description=This is a sample operation 1 in application 2>
      <OperationID>1</OperationID>
    </AzOperation>
    <AzOperation Guid=58e77672-8d9e-4cab-a677-83311378c6e0Name=Operation 2Description=This is a sample operation 2 in application 2>
      <OperationID>2</OperationID>
    </AzOperation>
  </AzApplication>
</AzAdminManager>

You will typically use the Authorization Manager console (azman.msc) to edit this file. Instead of having to describe a rather lengthy and cumbersome manual process you would have to go through every time to open XML policy store in the AzMan MMC console, I created a command file you can configure as an external editor in Visual Studio.

Working with the authorization policy
  • Right-click AuthorizationStore.xml in Solution Explorer and select “Open With” in the context menu.
  • In the Open With dialog, click the Add button.

image

  • In the Add Program dialog, click the “…” button and select AzMan.cmd installed by default in the C:\Program Files\T4 Toolbox\T4Toolbox\AzMan folder; enter Authorization Manager as Friendly Name and click the OK button.
  • In the Open With dialog, select newly added Authorization Manager item and click the OK button.

image

Note that Authorization Manager console opens in Administrator mode by default, which does not allow you to see Operation Definitions.

  • To edit operations, switch the console to Developer mode by clicking the Authorization Manager node and selecting Action->Options from the main menu .

image

While implementing an application, developer defines low-level security operations in the AzMan policy and adds application code to perform the authorization checks.  Business analyst uses the operation definitions provided by the developer to define business-level tasks and roles that describe security policy in terms meaningful to its users. System administrator defines groups and assigns groups and individual users to application roles provided by the business analyst. As long as the application itself doesn’t need to change, business analyst and system administrator can design, implement and change the authorization policy without requiring developer to change the application.

  • To save changes made in the authorization policy, simply close the Authorization Manager window.
  • To open the XML file in Authorization Manager next time, you will only need to select Open With from the context menu in Solution Explorer and choose Authorization Manager in the Open With dialog.

Note that Authorization Manager console saves XML policy file without formatting. To make the file easier to read and track changes in the source control history, consider formatting the XML in Visual Studio (Edit->Advanced->Format Document) before checking it in.

Deploying the authorization policy

In order to use the authorization policy, you will need to deploy it with your application. imageThe simplest way to do it is by copying the AzMan XML file to the directory where the executable runs.

  • Select AuthorizationStore.xml in the Solution Explorer and change its “Copy to Output Directory” property to “Copy if newer“.

This approach works best during development. It will work for production deployment as well, however you may improve performance and security by deploying the authorization policy to an Active Directory store instead.

AuthorizationStore.tt

This file is a T4 code generation file. It uses AzManWrapperGenerator class provided by T4 Toolbox to generate a strongly-typed C# class for accessing the authorization policy defined in the AuthorizationStore.xml.


<#
// <copyright file=”AuthorizationStore.tt” company=”Catapult Systems”>
//  Copyright © Catapult Systems. All Rights Reserved.
// </copyright>
#>
<#@ template language=C#hostspecific=True#>
<#@ output extension=.cs#>
<#@ include file=T4Toolbox.tt#>
<#@ include file=T4Toolbox\AzMan.tt#>
<#
    // Generate a strongly-typed class for performing authorization checks
    // against an AzMan store defined in the specified XML file.
    AzManWrapperGenerator generator = new AzManWrapperGenerator();
    generator.AzManXmlFile = “AuthorizationStore.xml”;
    generator.Namespace = “AzManPot”;
    generator.Run();
#>

For each application defined in the authorization policy, AuthorizationStore.tt generates a separate enumerated type. You will have Application1Operation.cs and Application2Operation.cs generated out of the box based on the sample policy in AuthorizationStore.xml. The enum defines one item for each operation defined by the AzMan policy. You will use the individual enum items when performing authorization checks.

// <autogenerated>
//   This file was generated by T4 code generator AuthorizationStore.tt.
//   Any changes made to this file manually will be lost next time the
//   file is regenerated.
// </autogenerated>
using System; 

namespace AzManPot
{
    /// <summary>
    /// This is a sample application 1
    /// </summary>
    public enum Application1Operation
    {
        /// <summary>
        /// This is a sample operation 1 in application 1
        /// </summary>
        Operation1 = 1, 

        /// <summary>
        /// This is a sample operation 2 in application 1
        /// </summary>
        Operation2 = 2
    }
}

AuthorizationStore.tt also generates a C# class (AuthorizationStore.cs) that encapsulates uses AzMan’s primary interop assembly (Microsoft.Interop.Security.AzRoles.dll) to perform authorization checks. Note C# code is automatically generated only the first time you add the AuthorizationStore.xml to your project. Remember to re-run the generator any time you modify operations in any of the applications defined in the AzMan policy.

  • Right-click AuthorizationStore.tt in the Solution Explorer and select “Run Custom Tool” to regenerate the wrapper class and the enumerations.
Performing authorization checks in your application
  • Create a new instance of the AuthorizationStore class. AuthorizationStore constructor takes a URL that defines location of the authorization store. It can point to an XML file as shown below or a store in Active Directory.
AuthorizationStore store = new AuthorizationStore(
    “msxml://” + Environment.CurrentDirectory + \\AuthorizationStore.xml);

Note that in this example we are hard-coding the URL. In production code, it is best to store it as a connection string in the application configuration file.

  • Call the Authorize method to check whether current user is authorized to perform a given operation. Authorize will throw SecurityException if the user’s role assignment in AzMan policy doesn’t allow performing the specified operation.
store.Authorize(Application1Operation.Operation2);
Console.WriteLine(“Performing Operation 2″);

  • If your application needs to gracefully reduce its functionality when user is not authorized to perform a particular operation, use CanPerform method which returns a boolean value instead of throwing an exception.
if (store.CanPerform(Application1Operation.Operation1))
    Console.WriteLine(“Performing Operation 1″);
else
    Console.WriteLine(“{0} is not authorized to perform {1}”,
        Thread.CurrentPrincipal.Identity.Name,
        Application1Operation.Operation1);

Note that Authorize and CanPerform methods shown above rely on the WindowsIdentity supplied by the CurrentPrincipal. In windows and console applications, you can configure AppDomain principal policy to automatically supply this value based on the identity of the user running the application.

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

In server applications, such as WCF web services or ASP.NET applications, this value is also automatically provided by the .NET framework.

If you need to authorize a user who is different from the user currently accessing the application, you can use the overloaded versions of Authorize and CanPerform methods that take WindowsIdentity as an additional parameter. This can be useful when implementing something like “manager override” functionality in line-of-business applications.

WindowsIdentity manager = // …
bool authorized = store.CanPerform(manager, Application1Operation.Operation1);
// or
store.Authorize(manager, Application1Operation.Operation1);

Customizing code generation

AzManWrapperGenerator provides the following properties you can use to customize code generation.

  • AzManXmlFile. Gets or sets the name of the XML file which defines the AzMan authorization store for which the strongly-typed wrapper needs to be generated. The initial value for this property is supplied when you add AuthorizationStore.xml to your project. You will need to update it manually if you rename the XML file. This property supports relative and absolute paths.
  • Namespace. Gets or sets the name of the namespace in which the wrapper class and enumerations will be generated. The initial value for this property is supplied when you add AuthorizationStore.xml to your project. You will need to update it manually if you move AuthorizationStore.tt to another project or another folder within the same project.

Conclusion

The Authorization Store template and code generator described in this article allow you to quickly implement task-based security in your application based on AzMan authorization policy. Unlike ASP.NET Role Manager, the generated wrapper class allows you to implement authorization checks at the operation level, which is what AzMan was designed to do. Unlike ASP.NET Role Manager of the Enterprise Library, the generated wrapper class allows you to use strongly-typed enumerations instead of string literals to specify operations. And unlike Authorization Interoperability Wrapper, the generated wrapper class is a low easier to use as it was designed to be consumed from .NET code as opposed to an ActiveX scripting.

This code generator does not yet solve the problem of deploying the AzMan authorization policy defined in XML during application development to an Active Directory store for use during production.

Download


Write a Comment

Take a moment to comment and tell us what you think. Some basic HTML is allowed for formatting.

Reader Comments

Nice - my new project is using the .Net SQL Authorization Manager; (http://sourceforge.net/projects/netsqlazman/). We should be able to reuse the ideas in this template to support that tool.

Thanks for mentioning this product, Jeff. I glanced over the documentation on SourceForge, it looks like the API is comparable to AzMan’s, so it should be possible. How are you planning to store the authorization policy during development? Does NetSqlAzMan allow using XML files?

Going from memory it has an XML file that you can import and export from their MMC snap in. So the same pattern you created for AzMan should work.

I already have the equivalent “Check Operation” code integrated into a proof of concept – it isn’t a COM call of course – it calls the library that in turn uses LINQ to SQL.

One additional comment - while Oleg provides instructions to deploy the Authorization Policy XML file, the XML file is really provided as a developer tool.

Actual enterprise implementations will use either Active Directory (typically via an Application Directory Application Mode instance) or, with Windows Server 2008 and/or Vista, SQL Server as the backing store for the Application Policy.

None of this affects the generation process; generating from the XML file is still valid, but deployment of would likely be to load the XML file into one of the other backing stores.

Good point, Jeff. Thanks for bringing this up. Can you share any practical reasons to deploy AzMan authorization policy in production to Active Directory or SQL as opposed to an XML file?