Saturday, March 30, 2013

WCF Security - AzMan [Windows AuthoriZation Manager]

AzMan is the short-form for Windows AuthoriZation Manager. This is one of the option for Role Based Security for enterprise level applications. AzMan provides runtime and GUI tool for managing Role-Based Access Control (RBAC) authorization policies in the form of a MMC Snap-in.

AzMan allows our systems to be divided into various scopes and operations. It allows assigning certain roles mapped to these operations. Now the application just need to determine from AzMan whether the requesting user has permissions to perform the requested operation based on the role assignment to the user. These roles can very easily be mapped to the Windows groups as well but we can also add users directly to these roles. It provides the opportunity to factor out the security logic from the applications and allows to define the authorization policies totally outside the application. It also allows to use scripts [VBScript / JScript] and allows parameter passing for more fine grained security policies. Since the authorization policies has been factored out of the application, it is very easy to assign the responsibility for managing security roles to security administrators. The GUI is based on Microsoft Management Console but it completely supports creating new GUI using the API. The MMC and related runtime libraries are available in %Windir%/System32 folder. You can see in the below image that Azman runtime and GUI are available in Windows 7 out of the box.



The purpose of this post is to see how we can use Authorization Manager to define role based security for our WCF Services. Along the way, we would add the necessary details about using AzMan but it should not be considered as a comprehensive discussion about AzMan.

It has been termed as Microsoft's Best Kept secret. Although this is supported in Windows Server 2012, there are hints that it might be discontinued for future releases. I think this is because of a better tool, Windows Identity Foundation, which I think Microsoft sees as more strategic intra and inter-orgranization role based access control. This is from MSDN:

AzMan is available for use in the following versions of Windows: Windows Server 2012, Windows 8, Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, or Windows XP. It may be altered or unavailable in subsequent versions.

But its use with Active Directory Federation Services [ADFS] provides hope for its continued support. Again from MSDN

AD FS used with Active Directory Lightweight Directory Services (AD LDS) as an identity provider for authentication and Windows Authorization Manager (AzMan) for control of access policy provides a complete solution to extending Web applications to trusted organizations.

AzMan Terminologies
  • Operation: Operations are the unit for defining security. They are assigned with a unique numbers which are used by application code. We can only create operations in Developer Mode in AzMan MMC.

  • Task: Operations can be grouped together in a task. A task can also be based on other tasks. We can even define VBScript / JScript business rules to be executed with the task. This allows us to defined parameterized rules. We are not using business rules in this example but you can enhance it to restrict the trader for the number of shares which can be traded in a single trade.

  • Authorization Store: Authorization store is the storage of these security rules. It can simply be an xml file. Recent AzMan allows SQL Server to be defined as an authorization store. We can even use Active Directory Lightweight Directory Service or ADAM as authorization store.

  • Application: An application is a conceptual concept to group scopes and operations. It allows creations of operations, grouping them into tasks, creation of roles and assigning them to these operations and tasks.

  • Scope : An application can also be divided into different scopes which can have their own operations, tasks and roles assignment.

  • Role: Role is an entity which can be assigned rights on operations / tasks. It is the basis of Role Based Access Control [RBAC]. We can create roles using the AzMan GUI and assign them to Domain Users / Groups. AzMan also supports dynamic roles using business rules where a user can be determined to belong to a role based on this dynamic rule. Like e.g. if a user has a Title as Manager, then he belongs to this role. A role can also be based on other fine-grained roles. These roles are assigned to individual user / groups based on the role assignment supported in AzMan GUI.

  • Business Rule: Business rules provide dynamic nature to AzMan. Business rules can be used for parameterized operations or roles. AzMan supports business rules in VBScript and JScript. You can define timeout for execution of business rules. They can also be disabled altogether. In that case, if you have business rules defined than the AzMan API cannot be used for permission check.
Supported Repositories
Following repositories are supported to create authorization stores in Azman.
  1. XML

  2. AD DS: Active Directory Domain Service or ADAM [Active Directory Application Mode]

  3. Microsoft SQL Server (new for Windows Vista and Windows Server 2008)
Starting AzMan
As we have discussed, AzMan is a Microsoft Management Console (MMC) based application, we can use it from MMC window. We just need to add a SnapIn to the MMC console and we should be good to go.



Now we can simply add the SnapIn using Add / Remove SnapIn feature of Microsoft Management Console [MMC].



The SnapIn should be available for selection as follows:



Alternatively, we can use the AuthorizationManager SnapIn directly. Just use AzMan.msc from the Run command.



The snapIn should appear as follows:



In the Microsoft Management console window, it should be available under Console Root:



Creating AzMan Authorization Store
In order to create authorization store, we must use AzMan in Developer Mode. We can change the selection by the following dialog available through Action -> Option menu.



Let's use the authorization manager to create an XML based authorization store. Based on the above selection of Developer Mode, we should see the following menu, let's select to create a new authorization store.



Let's make the necessary selection for creation of Xml based store. We need to specify where we want to keep the xml file for the store. We also need to make a selection of the schema. It must be remembered that 2.0 can't be downgraded to version 1.0. Additionally this cannot be accessed by clients using 1.0. But if you are just introducing AzMan in your organization, you should be making the newer schema selection.



Now let's create a new application group by right clicking the Groups folder on the left. The following dialog should appear:



It must be remembered that an application group is a group of users, computers or other security principals. There are three types of application groups: Basic Application Group, LDAP Query Application Group and Business Rule Application Group. These types are based on how the membership would be determined for the group. For an LDAP Query applicaiton group, it is determined dynamically using LDAP [Lightweight Directory Access Protocol] queries. For a Business rule application group, it is also determined dynamically but here it is determined by the scripts written in a scripting language including JScript and VBScript. It can be simpler for a basic application group where it can be determined by windows groups. It also allows to define the membership using LDAP queries.

In order to define Basic application group, let's first create a local group using Computer Management. Let's name it as Traders. At this time, we are not assigning the current windows user to the group.



Now let's use Traders group for our basic application group in Authorization Manager. We have just selected the group using Windows group selection dialog.



As we are updating the security selections, the xml store is being continously updated to include the details. Let's see how it is growing:



If we look at the contents of the store, we can realize how simply the membership is being defined. Here Trader group's SID is being used for the membership.


Creating AzMan Application
All the management of authorization store is done using the same Authorization Manager MMC SnapIn. Just right click the authorization store, you should see the option for creating an application.



Let's create an application for our WCF Service. We are naming the application as TradeExecutionApp.



Authorization Manager applications allow us to define roles, tasks and operations. Yes, they cannot be shared across the applications. This kind of make sense too. An application can have local authorization manager roles as well. The roles can be assigned to Windows / Domain groups or authorization manager groups. For authorization manager roles, the mapping can be defined for local or global authorization manager groups.



Now let's add two operations ExecuteTrade and CancelTrade. The operations should be assigned with a unique operation number. This number would be used when we would be using this policy in an application. An administrator cannot mess with operations because the application is dependent on the operation definitions. Let's create a task and assign the two operations to the newly created task as follows:



We need to assign the tasks and operations to a role to define security privileges. Authorization Manager supports creating roles. Here we are creating a role, named TradeExecutionRole and adding the task created above to the role. The roles can be assigned with operations or tasks. These roles can also be based on other roles. This can be used to define more fine grained security roles and then combine them to create roles for different related features.



These roles can be assigned to a group. Than authorization manager or a Windows / Domain group. Let's assign the role to TradeExecutors global authorization manager group.



As we have been adding these roles, tasks, operations and assignments, Windows Authorization Manager has kept updating the Xml authorization store. Let's see how it has kept the definition updated:

Using AzMan Roles for Securing Applications
This is the area which has very limited information available on the net. First of all, on my Windows 7 Ultimate machine, the folder is empty. The folder can be founded as being recommeded for referencing Microsoft.Interop.Security.AzRoles assembly. To be fair to the recommeders, I don't have a server machine where I am creating this application [http://msdn.microsoft.com/en-us/library/aa480244.aspx]



I can find the assembly can be found in the Global assembly cache.



To be exact, the Microsoft.Interop.Security.AzRoles assembly can be found in GAC_32 folder in global assembly cache.



We can browse to the GAC to add this assembly in our project.



This is actually an interop assembly for AzRolesLib.dll. We can also add the direct reference of AzRolesLib using Type Library. This would create an interop assembly in obj\Debug folder. Here we have added the reference of the library in a sample project.



Let's use AzMan based Role Based Access Control in our WCF application TradeExecutionServiceLib. Let's create a managed wrapper around the AzMan runtime libraries access as follows:



Let's create an enumeration for the operations for the application. This would help us avoiding to use the operation numbers spread across the entire code base. It must be remembered that AzMan Admin MMC doesn't allow to create / modify the operations in the Administrator mode. If we need more operations then we need to develop for implementing those operations in our applications, hence developer mode for AzMan MMC. You can see that here we have used the same operation numbers as we defined in AzMan for creation of these operations.

Now let's define an interface for checking the access on an operation for an identity. This would allow us to change the RBAC move to a different store than Windows Authorization Manager.

Now let's provide AzMan based implementation of the above interface. The type has a constructor where it requires the connection string and application name. It also has a method to implement the method checking the access rights of an IIdentity on an Operation.

Now since we have policy definition and required code completed now, we can use it in our Trade Execution Service. You can get the code from our previous post and add the above code as an existing project to the solution. You would need to add an assembly reference into our service project. It would also be required to get rid of custom Service Authorization Manager from code and App.Config.

AzMan and Enterprise Library 5
Enterprise Library - Security Application Block allows defining authorization providers. The authorization provider allows introducing security as an orthogonal pluggable concept. AuthorizationProvider.Authorize takes an IPrincipal and operation name as an input. This is similar to the requirement of AzMan. You can read further about how we can use AzMan with Security Application Block in Enterprise Library 5.0. You can even use the AzMan managed wrapper created here and use it with the Authorization Provider.

http://msdn.microsoft.com/en-us/library/ff664559(v=pandp.50).aspx

You can also find a few nuget packages provided by Microsoft and other community members in order to provide ease of development using AzMan. You can specially look at the security provider package for Enterprise Library 5.0.



Further Reading / Reference?

Download Code

Thursday, March 21, 2013

WCF Security - Service Authorization Manager

In the previous posts, we have seen two possible options of authorization / access control including PrincipalPermission and directly using ServiceSecurityContext for authorizing users from the same active directory domains. With PrincipalPermission() we need to provide the security logic on each service operation with an option of using PrinicipalPermissionAttribute. Using ServiceSecurityContext, we included the authorization logic in service operation code which makes it convoluted. What if we need to only authorize certain users for the service i.e. all operations of the service. The feature can be implemented by using the extensibility features in WCF. We can use ServiceAuthorizationManager for the same.

Based on Security Architecture document on MSDN, ServiceAuthorizationManager is used to perform two steps for the incoming message. The first step is Authorization Policies Evaluation Stage, Here It is used to evaluate authorization policies where claims can also be added to the evaluation context. Here external authorization policies can also be used. As the second step [Service Authorization stage], the authorization policies can be used to perform the actual authorization. In the document, the steps are specified as follows in the WCF pipeline:



ServiceAuthorizationManager is provided as follows:



As we can see that there are two overloads of CheckAccess() method. Additionally, there are two virtual methods CheckAccessCore() and GetAuthorizationPolicies(). If we dotPeek the code, we can verify the flow described by the MSDN document. As you can see that it iis first calling GetAuthorizationPolicies() and then after using the authorization policies to create a ServiceSecurityContext, it is using the CheckAccessCore() method. The default implementation of CheckAccessCore() is PERMIT ALL i.e. it returns true, we can override this to perform the required authorization.



In order to understand it further let us add a custom definition of ServiceAuthorizationManager. It is non-sealed so we can directly inherit from it and override the virtual members. Based on the code flow of CheckAccess() described above, we just need to override CheckAccessCore() and GetAuthorizationPolicies() methods. For now, let's just use the logic provided by the base class i.e. ServiceAuthorizationManager.

Now in order for the service to use this, we must add this behavior, let's update the App.Config. As you can see we are still using WindowsGroups as the principal permissions. We would be providing the actual authorization using the same groups.

In order to test that the service authorization manager is actually being used by the service. Add some breakpoints and execute the code, you should see that GetAuthorizationPolicies() is called first followed by CheckAccessCore() method.



Here we have used the same WCF Test Client as we have been using in the previous examples:



Now let us provide the same authorization logic we have provided in the last two examples. We only want subjects from Traders group to have access to our service. Since the same WCF pipeline is used for metadata requests as well, we need to first determine if this is such request. If so we can allow the operation. There is no user specific security information for metadata request including claims and domain groups. For other service operations as well, the header action is set accordingly.

Let's execute the code, as you can see the authorization logic is correctly being used.



Here we have provided the code for service level authorization logic. For more fine grained security based, we can use the request header actions.

Download

Tuesday, March 19, 2013

WCF Role Based Authorization using ServiceSecurityContext

In this post we are going to discuss how we can use ServiceSecurityContext for authorization. Although it is not recommended a lot but I have seen it being used in organizational setups more often than usual. In the last post, we discussed about PrincipalPermission based roles authorization. Here roles are Windows / Domain groups. Since the service is able to validate the users based on these roles, it means that service has access to those groups from the client request. The whole idea is to access these roles and use them for our purpose. One such use is authorization. Actually, this information is part of message through SecurityMessageProperty.



We will be building on the previous example so you might want to get that code first [http://www.shujaat.net/2013/03/wcf-role-based-authorization-using.html]. Let's assume that we have the same security requirement as the previous example and we want that only those requesters which belong to the Traders group should be able to execute Trades. Let's update the service implementation as follows:

The above code is practically doing the same thing as in the previous post i.e. only allow Traders to execute the trades. I would specially emphasis to look at the definition of newly added AuthorizeUser() method. I have refactored it into a separate method just in case other service operations from the same service might require the same authorization then the would provide reusability. We can also define the authorize user in a configuration file or just read it from database and use it here for authorization. This would allow us to change it without requiring to recompile the code.

The first problem is to get our hands on the requester's roles. As discussed above, ServiceSecurityContext allows us to get the list of the groups from the request. It provides us the SIDs for the groups which can be translated into their names. Then we just need to check if the groups' collection has our authorized group. If so, then just allow the request to continue, otherwise, throw an exception.

The above is very simple implementation of the trade execution authorization. This example can be extended into allowing certain users to execute a certain kind of trade. In that case, we can create domain groups for each role and check if the requester belongs to such role before having allowing him to continue. In the following example, the requester must belong to MSFTTraders group in addition to being a trader in order to execute MSFT instrument trading.

Based on the above code, if I request the trade execution as follows then it should flow through fine. This is because, we have added the current user to Traders group. Since we are trading GOOG, it doesn't require any further authorization.



On the other hand, if we were trading MSFT, we should get the unauthorized access, as the current user doesn't belong to MSFTTraders group.



We get the following exception for the current user.



These roles can also be used to define the role specific service workflows. We can require requester, belonging to a certain groups, to get authorized or send an email to a control group watching the activities of traders which are fed to some regulatory authorities interested in such information. But I would leave that to work on that.

Download


Monday, March 18, 2013

WCF Role Based Authorization using Principal Permissions for Windows Groups

In the last few post we have been trying to set the stage to start discussing about creating Identity aware application architecture using Windows Identity Foundation [WIF]. We have been going through these posts to ease ourselves into the technology. This post is also to set one step towards that direction. This is to discuss role based security outside the Identity and Claims world. Please remember that this is the most common way we have been implementing security authentication and authorization in our services specially inside the firewall in an intranet organization setup.

Let's consider our organization as a financial type of organization where we have different applications and services to help the employees carrying out their activities. One such users are traders. They execute trades which are then forwarded to any specific exchange for placement. We need to make sure that only traders are allowed to execute trade. One such way is to check at the service level if the requester is a trader and allow the operation only under such case.

In WCF scenarios for a Windows Active Directory based domains, users belong to different domain groups. These groups are used by applications to determine the user privileges before executing the actual operation. The same approach has been traditionally taken to implement security for our services. This is exactly what we would be trying to discuss in this post. For our organization, let us assume that all traders belong to Traders group.

Let's start by creating a WCF Service Library project, TradeExecutionServiceLib.



Now let's update the name of the service contract and the implementation to ITradeExecutor and TradeExecutor respectively. Doing it on the solution explorer level would ensure that the class names are updated inside their respective files. This should also update the service configuration in App.Config file.



Now let us update ITradeExecutor as follows:

Here we have also included a service operation, ExecuteTrade(). This is certainly very simple way on the service side for looking at the trades execution but this should be enough to understand the concept of role based security authorization in WCF, which is the purpose of today's post. This requires the instrument's symbol and quantity to be passed as input parameters. Now we update the service implementation as follows:

The implementation is just writing the details about the symbol and traded quantity on the console. Now let us add authorization code. We need to make sure that only traders belonging to Traders group have access to ExecuteTrade() operation. In WCF and code access security scenarios, this can easily be implemented using PrincipalPermission attribute from System.Security.Permissions namespace in mscorlib assembly. We can also directly use PrincipalPermssion class in a non-declarative way.

Decorating Service Operations with PrincipalPermissionAttribute
One way to authorize user's role is to decorate the operation with PrincipalPermissionAttribute. Here Role would mean the Windows group we are specifically looking for. Now this becomes the responsibility of runtime hosting the service to ensure that the user of the service is a member of the specified group and deny access otherwise.

Now we need to test if the authorization logic is actually working. Since this is a very simple service, we don't need to build a special client just to test the service. Here we can simply use WCF Test Client installed using the framework. We don't even need to host this as Visual Studio would automatically host it to the default WCF Service Host. run this with the default service configuration. Just make sure that you have the service project set as start up project in the solution. Since we have only one project in the solution, this is the default case here. You should see the following toast appear in the system tray when you run the service.



If you double click the icon on the tray, you should see that service is hosted and the status should show as Started.



This should also launch WCF Test Client with the operations listed on the service.



Let us provide the input arguments for ExecuteTrade operation and hit Invoke. Since were debugging it, we should be able to see the following security exception in the visual studio editor:



If you continue the execution then you should see the following on the WCF Test Client side which just shows the client that there is something wrong with the request. When we write our custom clients we should be handling this case more gracefully showing the user the exact cause of the error or how to request permissions if he is a legitimate user of the service.



Since the service operation requires the user to belong to a certain role, it blows up as there is no such membership for the requesting user. Not even such a group exists on the machine [CHEETA]. To keep it simple, let us create a Windows Group using the Computer Management tool as follows:



Let's add the user (requester) to the Traders group now. See the highlighted information requiring the user to login again in order for the changes to take effect.



Now let us update ServiceModel section of the service configuration in App.Config to use Windows security. Here we have updated the binding to net TCP. We have also updated authorization behavior use Windows Accounts.

In order to test that the logic is actually working let us debug the code. Let us insert a break point on the ExecuteTrade operation side and run the service. As described previously the service is hosted and WCF Test Client is launched, we provide the same input arguments as before ("MSFT" and 100) and invoke service operation. since the user has such membership now, the security authorization logic calls the method and hits the break point.



The class hierarchy of PrinicipalPermissionAttribute is as follows:



Non-Declarative Permission Demands
In the above example we provided the required membership requirements by adding PrinicipalPermissionAttribute to the operation contract implementation. The same behavior can be achieved by doing the same thing in the code. The unauthorized access would be determined by WCF Service pipeline and an exception would be generated which would result in a fault for the user. In the below code, we are just updating the code to demand membership using the same Principal Permission, but using code.


The definition of PrincipalPermission is as follows:



If we look at the definition of PrincipalPermissionAttribute, it is using the same IPermission.



Download Code