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.


No comments: